Imported Upstream version 1.8.0 upstream/1.8.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:07 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:07 +0000 (11:15 +0900)
488 files changed:
.bazelrc [new file with mode: 0644]
AUTHORS
BUILD.bazel
COPYING
Makefile.am
Makefile.in
NEWS
README
WORKSPACE [deleted file]
WORKSPACE.bazel [new file with mode: 0644]
aclocal.m4
ar-lib
compile
configure
configure.ac
depcomp
install-sh
missing
src/Makefile.in
src/bin/Makefile.in
src/bin/fstarcsort-main.cc
src/bin/fstarcsort.cc
src/bin/fstclosure-main.cc
src/bin/fstclosure.cc
src/bin/fstcompile-main.cc
src/bin/fstcompile.cc
src/bin/fstcompose-main.cc
src/bin/fstcompose.cc
src/bin/fstconcat-main.cc
src/bin/fstconcat.cc
src/bin/fstconnect-main.cc
src/bin/fstconnect.cc
src/bin/fstconvert-main.cc
src/bin/fstconvert.cc
src/bin/fstdeterminize-main.cc
src/bin/fstdeterminize.cc
src/bin/fstdifference-main.cc
src/bin/fstdifference.cc
src/bin/fstdisambiguate-main.cc
src/bin/fstdisambiguate.cc
src/bin/fstdraw-main.cc
src/bin/fstdraw.cc
src/bin/fstencode-main.cc
src/bin/fstencode.cc
src/bin/fstepsnormalize-main.cc
src/bin/fstepsnormalize.cc
src/bin/fstequal-main.cc
src/bin/fstequal.cc
src/bin/fstequivalent-main.cc
src/bin/fstequivalent.cc
src/bin/fstinfo-main.cc
src/bin/fstinfo.cc
src/bin/fstintersect-main.cc
src/bin/fstintersect.cc
src/bin/fstinvert-main.cc
src/bin/fstinvert.cc
src/bin/fstisomorphic-main.cc
src/bin/fstisomorphic.cc
src/bin/fstmap-main.cc
src/bin/fstmap.cc
src/bin/fstminimize-main.cc
src/bin/fstminimize.cc
src/bin/fstprint-main.cc
src/bin/fstprint.cc
src/bin/fstproject-main.cc
src/bin/fstproject.cc
src/bin/fstprune-main.cc
src/bin/fstprune.cc
src/bin/fstpush-main.cc
src/bin/fstpush.cc
src/bin/fstrandgen-main.cc
src/bin/fstrandgen.cc
src/bin/fstrelabel-main.cc
src/bin/fstrelabel.cc
src/bin/fstreplace-main.cc
src/bin/fstreplace.cc
src/bin/fstreverse-main.cc
src/bin/fstreverse.cc
src/bin/fstreweight-main.cc
src/bin/fstreweight.cc
src/bin/fstrmepsilon-main.cc
src/bin/fstrmepsilon.cc
src/bin/fstshortestdistance-main.cc
src/bin/fstshortestdistance.cc
src/bin/fstshortestpath-main.cc
src/bin/fstshortestpath.cc
src/bin/fstsymbols-main.cc
src/bin/fstsymbols.cc
src/bin/fstsynchronize-main.cc
src/bin/fstsynchronize.cc
src/bin/fsttopsort-main.cc
src/bin/fsttopsort.cc
src/bin/fstunion-main.cc
src/bin/fstunion.cc
src/extensions/Makefile.in
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compact/compact16_acceptor-fst.cc
src/extensions/compact/compact16_string-fst.cc
src/extensions/compact/compact16_unweighted-fst.cc
src/extensions/compact/compact16_unweighted_acceptor-fst.cc
src/extensions/compact/compact16_weighted_string-fst.cc
src/extensions/compact/compact64_acceptor-fst.cc
src/extensions/compact/compact64_string-fst.cc
src/extensions/compact/compact64_unweighted-fst.cc
src/extensions/compact/compact64_unweighted_acceptor-fst.cc
src/extensions/compact/compact64_weighted_string-fst.cc
src/extensions/compact/compact8_acceptor-fst.cc
src/extensions/compact/compact8_string-fst.cc
src/extensions/compact/compact8_unweighted-fst.cc
src/extensions/compact/compact8_unweighted_acceptor-fst.cc
src/extensions/compact/compact8_weighted_string-fst.cc
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/compress/compressscript.cc
src/extensions/compress/fstcompress-main.cc
src/extensions/compress/fstcompress.cc
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/const/const16-fst.cc
src/extensions/const/const64-fst.cc
src/extensions/const/const8-fst.cc
src/extensions/far/Makefile.am
src/extensions/far/Makefile.in
src/extensions/far/build_defs.bzl [new file with mode: 0644]
src/extensions/far/far-class.cc
src/extensions/far/farcompilestrings-main.cc
src/extensions/far/farcompilestrings.cc
src/extensions/far/farconvert-main.cc [new file with mode: 0644]
src/extensions/far/farconvert.cc [new file with mode: 0644]
src/extensions/far/farcreate-main.cc
src/extensions/far/farcreate.cc
src/extensions/far/farequal-main.cc
src/extensions/far/farequal.cc
src/extensions/far/farextract-main.cc
src/extensions/far/farextract.cc
src/extensions/far/farinfo-main.cc
src/extensions/far/farinfo.cc
src/extensions/far/farisomorphic-main.cc
src/extensions/far/farisomorphic.cc
src/extensions/far/farprintstrings-main.cc
src/extensions/far/farprintstrings.cc
src/extensions/far/farscript.cc
src/extensions/far/getters.cc
src/extensions/far/script-impl.cc
src/extensions/far/stlist.cc
src/extensions/far/strings.cc
src/extensions/far/sttable.cc
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/linear/fstlinear-main.cc
src/extensions/linear/fstlinear.cc
src/extensions/linear/fstloglinearapply-main.cc
src/extensions/linear/fstloglinearapply.cc
src/extensions/linear/linear-classifier-fst.cc
src/extensions/linear/linear-tagger-fst.cc
src/extensions/linear/linearscript.cc
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/lookahead/arc_lookahead-fst.cc
src/extensions/lookahead/ilabel_lookahead-fst.cc
src/extensions/lookahead/olabel_lookahead-fst.cc
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/mpdt/mpdtcompose-main.cc
src/extensions/mpdt/mpdtcompose.cc
src/extensions/mpdt/mpdtexpand-main.cc
src/extensions/mpdt/mpdtexpand.cc
src/extensions/mpdt/mpdtinfo-main.cc
src/extensions/mpdt/mpdtinfo.cc
src/extensions/mpdt/mpdtreverse-main.cc
src/extensions/mpdt/mpdtreverse.cc
src/extensions/mpdt/mpdtscript.cc
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/ngram/bitmap-index.cc
src/extensions/ngram/ngram-fst.cc
src/extensions/ngram/nthbit.cc
src/extensions/pdt/Makefile.am
src/extensions/pdt/Makefile.in
src/extensions/pdt/getters.cc
src/extensions/pdt/pdtcompose-main.cc
src/extensions/pdt/pdtcompose.cc
src/extensions/pdt/pdtexpand-main.cc
src/extensions/pdt/pdtexpand.cc
src/extensions/pdt/pdtinfo-main.cc
src/extensions/pdt/pdtinfo.cc
src/extensions/pdt/pdtreplace-main.cc
src/extensions/pdt/pdtreplace.cc
src/extensions/pdt/pdtreverse-main.cc
src/extensions/pdt/pdtreverse.cc
src/extensions/pdt/pdtscript.cc
src/extensions/pdt/pdtshortestpath-main.cc
src/extensions/pdt/pdtshortestpath.cc
src/extensions/python/Makefile.in
src/extensions/python/cintegral_types.pxd
src/extensions/python/cios.pxd
src/extensions/python/cpywrapfst.pxd
src/extensions/python/cutility.pxd
src/extensions/python/pywrapfst.cpp
src/extensions/python/pywrapfst.pxd
src/extensions/python/pywrapfst.pyx
src/extensions/special/Makefile.am
src/extensions/special/Makefile.in
src/extensions/special/phi-fst.cc
src/extensions/special/rho-fst.cc
src/extensions/special/sigma-fst.cc
src/include/Makefile.am
src/include/Makefile.in
src/include/fst/accumulator.h
src/include/fst/add-on.h
src/include/fst/arc-arena.h
src/include/fst/arc-map.h
src/include/fst/arc.h
src/include/fst/arcfilter.h
src/include/fst/arcsort.h
src/include/fst/bi-table.h
src/include/fst/cache.h
src/include/fst/closure.h
src/include/fst/compact-fst.h
src/include/fst/compat.h
src/include/fst/complement.h
src/include/fst/compose-filter.h
src/include/fst/compose.h
src/include/fst/concat.h
src/include/fst/connect.h
src/include/fst/const-fst.h
src/include/fst/determinize.h
src/include/fst/dfs-visit.h
src/include/fst/difference.h
src/include/fst/disambiguate.h
src/include/fst/edit-fst.h
src/include/fst/encode.h
src/include/fst/epsnormalize.h
src/include/fst/equal.h
src/include/fst/equivalent.h
src/include/fst/error-weight.h [new file with mode: 0644]
src/include/fst/expanded-fst.h
src/include/fst/expander-cache.h
src/include/fst/expectation-weight.h
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/compress/compressscript.h
src/include/fst/extensions/compress/elias.h
src/include/fst/extensions/far/compile-strings.h
src/include/fst/extensions/far/convert.h [new file with mode: 0644]
src/include/fst/extensions/far/create.h
src/include/fst/extensions/far/equal.h
src/include/fst/extensions/far/extract.h
src/include/fst/extensions/far/far-class.h
src/include/fst/extensions/far/far.h
src/include/fst/extensions/far/farlib.h
src/include/fst/extensions/far/farscript.h
src/include/fst/extensions/far/getters.h
src/include/fst/extensions/far/info.h
src/include/fst/extensions/far/isomorphic.h
src/include/fst/extensions/far/print-strings.h
src/include/fst/extensions/far/script-impl.h
src/include/fst/extensions/far/stlist.h
src/include/fst/extensions/far/sttable.h
src/include/fst/extensions/linear/linear-fst-data-builder.h
src/include/fst/extensions/linear/linear-fst-data.h
src/include/fst/extensions/linear/linear-fst.h
src/include/fst/extensions/linear/linearscript.h
src/include/fst/extensions/linear/loglinear-apply.h
src/include/fst/extensions/linear/trie.h
src/include/fst/extensions/mpdt/compose.h
src/include/fst/extensions/mpdt/expand.h
src/include/fst/extensions/mpdt/info.h
src/include/fst/extensions/mpdt/mpdt.h
src/include/fst/extensions/mpdt/mpdtlib.h
src/include/fst/extensions/mpdt/mpdtscript.h
src/include/fst/extensions/mpdt/read_write_utils.h
src/include/fst/extensions/mpdt/reverse.h
src/include/fst/extensions/ngram/bitmap-index.h
src/include/fst/extensions/ngram/ngram-fst.h
src/include/fst/extensions/ngram/nthbit.h
src/include/fst/extensions/pdt/collection.h
src/include/fst/extensions/pdt/compose.h
src/include/fst/extensions/pdt/expand.h
src/include/fst/extensions/pdt/getters.h
src/include/fst/extensions/pdt/info.h
src/include/fst/extensions/pdt/paren.h
src/include/fst/extensions/pdt/pdt.h
src/include/fst/extensions/pdt/pdtlib.h
src/include/fst/extensions/pdt/pdtscript.h
src/include/fst/extensions/pdt/replace.h
src/include/fst/extensions/pdt/reverse.h
src/include/fst/extensions/pdt/shortest-path.h
src/include/fst/extensions/special/phi-fst.h
src/include/fst/extensions/special/rho-fst.h
src/include/fst/extensions/special/sigma-fst.h
src/include/fst/factor-weight.h
src/include/fst/filter-state.h
src/include/fst/float-weight.h
src/include/fst/fst-decl.h
src/include/fst/fst.h
src/include/fst/fstlib.h
src/include/fst/generic-register.h
src/include/fst/heap.h
src/include/fst/icu.h
src/include/fst/intersect.h
src/include/fst/interval-set.h
src/include/fst/invert.h
src/include/fst/isomorphic.h
src/include/fst/label-reachable.h
src/include/fst/lexicographic-weight.h
src/include/fst/lookahead-filter.h
src/include/fst/lookahead-matcher.h
src/include/fst/map.h
src/include/fst/mapped-file.h
src/include/fst/matcher-fst.h
src/include/fst/matcher.h
src/include/fst/memory.h
src/include/fst/minimize.h
src/include/fst/mutable-fst.h
src/include/fst/pair-weight.h
src/include/fst/partition.h
src/include/fst/power-weight-mappers.h
src/include/fst/power-weight.h
src/include/fst/product-weight.h
src/include/fst/project.h
src/include/fst/properties.h
src/include/fst/prune.h
src/include/fst/push.h
src/include/fst/queue.h
src/include/fst/randequivalent.h
src/include/fst/randgen.h
src/include/fst/rational.h
src/include/fst/register.h
src/include/fst/relabel.h
src/include/fst/replace-util.h
src/include/fst/replace.h
src/include/fst/reverse.h
src/include/fst/reweight.h
src/include/fst/rmepsilon.h
src/include/fst/rmfinalepsilon.h
src/include/fst/script/arc-class.h
src/include/fst/script/arciterator-class.h
src/include/fst/script/arcsort.h
src/include/fst/script/arg-packs.h
src/include/fst/script/closure.h
src/include/fst/script/compile-impl.h
src/include/fst/script/compile.h
src/include/fst/script/compose.h
src/include/fst/script/concat.h
src/include/fst/script/connect.h
src/include/fst/script/convert.h
src/include/fst/script/decode.h
src/include/fst/script/determinize.h
src/include/fst/script/difference.h
src/include/fst/script/disambiguate.h
src/include/fst/script/draw-impl.h
src/include/fst/script/draw.h
src/include/fst/script/encode.h
src/include/fst/script/encodemapper-class.h
src/include/fst/script/epsnormalize.h
src/include/fst/script/equal.h
src/include/fst/script/equivalent.h
src/include/fst/script/fst-class.h
src/include/fst/script/fstscript-decl.h
src/include/fst/script/fstscript.h
src/include/fst/script/getters.h
src/include/fst/script/info-impl.h
src/include/fst/script/info.h
src/include/fst/script/intersect.h
src/include/fst/script/invert.h
src/include/fst/script/isomorphic.h
src/include/fst/script/map.h
src/include/fst/script/minimize.h
src/include/fst/script/print-impl.h
src/include/fst/script/print.h
src/include/fst/script/project.h
src/include/fst/script/prune.h
src/include/fst/script/push.h
src/include/fst/script/randequivalent.h
src/include/fst/script/randgen.h
src/include/fst/script/relabel.h
src/include/fst/script/replace.h
src/include/fst/script/reverse.h
src/include/fst/script/reweight.h
src/include/fst/script/rmepsilon.h
src/include/fst/script/script-impl.h
src/include/fst/script/shortest-distance.h
src/include/fst/script/shortest-path.h
src/include/fst/script/stateiterator-class.h
src/include/fst/script/synchronize.h
src/include/fst/script/text-io.h
src/include/fst/script/topsort.h
src/include/fst/script/union.h
src/include/fst/script/verify.h
src/include/fst/script/weight-class.h
src/include/fst/set-weight.h
src/include/fst/shortest-distance.h
src/include/fst/shortest-path.h
src/include/fst/signed-log-weight.h
src/include/fst/sparse-power-weight.h
src/include/fst/sparse-tuple-weight.h
src/include/fst/state-map.h
src/include/fst/state-reachable.h
src/include/fst/state-table.h
src/include/fst/statesort.h
src/include/fst/string-weight.h
src/include/fst/string.h
src/include/fst/symbol-table-ops.h
src/include/fst/symbol-table.h
src/include/fst/synchronize.h
src/include/fst/test-properties.h
src/include/fst/test/algo_test.h
src/include/fst/test/compactors.h
src/include/fst/test/fst_test.h
src/include/fst/test/rand-fst.h
src/include/fst/test/weight-tester.h
src/include/fst/topsort.h
src/include/fst/tuple-weight.h
src/include/fst/union-find.h
src/include/fst/union-weight.h
src/include/fst/union.h
src/include/fst/util.h
src/include/fst/vector-fst.h
src/include/fst/verify.h
src/include/fst/visit.h
src/include/fst/weight.h
src/include/fst/windows_defs.inc
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/encode.cc
src/lib/fst-types.cc
src/lib/fst.cc
src/lib/mapped-file.cc
src/lib/properties.cc
src/lib/symbol-table-ops.cc
src/lib/symbol-table.cc
src/lib/util.cc
src/lib/weight.cc
src/script/Makefile.am
src/script/Makefile.in
src/script/arciterator-class.cc
src/script/arcsort.cc
src/script/closure.cc
src/script/compile.cc
src/script/compose.cc
src/script/concat.cc
src/script/connect.cc
src/script/convert.cc
src/script/decode.cc
src/script/determinize.cc
src/script/difference.cc
src/script/disambiguate.cc
src/script/draw.cc
src/script/encode.cc
src/script/encodemapper-class.cc
src/script/epsnormalize.cc
src/script/equal.cc
src/script/equivalent.cc
src/script/fst-class.cc
src/script/getters.cc
src/script/info-impl.cc
src/script/info.cc
src/script/intersect.cc
src/script/invert.cc
src/script/isomorphic.cc
src/script/map.cc
src/script/minimize.cc
src/script/print.cc
src/script/project.cc
src/script/prune.cc
src/script/push.cc
src/script/randequivalent.cc
src/script/randgen.cc
src/script/relabel.cc
src/script/replace.cc
src/script/reverse.cc
src/script/reweight.cc
src/script/rmepsilon.cc
src/script/shortest-distance.cc
src/script/shortest-path.cc
src/script/stateiterator-class.cc
src/script/synchronize.cc
src/script/text-io.cc
src/script/topsort.cc
src/script/union.cc
src/script/verify.cc
src/script/weight-class.cc
src/test/Makefile.in
src/test/algo_test.cc
src/test/fst_test.cc
src/test/weight_test.cc
test-driver

diff --git a/.bazelrc b/.bazelrc
new file mode 100644 (file)
index 0000000..aa14d1b
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1,69 @@
+# Copyright 2015-2020 Google LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# OpenFst Bazel configuration file.
+# ---------------------------------
+# Based on TensorFlow options in:
+#   https://github.com/tensorflow/tensorflow/blob/master/.bazelrc
+#
+# Compiler options:
+#     c++17:                  Build with C++17 options (links with libc++)
+#     c++1z:                  Build with C++17 options (links with libc++)
+#     c++17_gcc:              Build with C++17 options (links with stdlibc++)
+#     c++1z_gcc:              Build with C++17 options (links with stdlibc++)
+#
+# Other build options:
+#     short_logs:       Only log errors during build, skip warnings.
+#     verbose_logs:     Show all compiler warnings during build.
+#     libc++:           Link against libc++ instead of stdlibc++
+
+# Suppress all warning messages.
+build:short_logs --output_filter=DONT_MATCH_ANYTHING
+build:verbose_logs --output_filter=
+build --config=short_logs
+
+# Allow builds using libc++ as a linker library. This is mostly for
+# OSSFuzz, so we also pass in the flags from environment to clean
+# build file.
+build:libc++ --action_env=CC
+build:libc++ --action_env=CXX
+build:libc++ --action_env=CXXFLAGS=-stdlib=libc++
+build:libc++ --action_env=PATH
+build:libc++ --define force_libcpp=enabled
+build:libc++ --linkopt -fuse-ld=lld
+
+# Build with C++ 17 features.
+build:c++17 --cxxopt=-std=c++1z
+build:c++17 --cxxopt=-stdlib=libc++
+build:c++1z --config=c++17
+build:c++17_gcc --cxxopt=-std=c++1z
+build:c++1z_gcc --config=c++17_gcc
+
+# Enable using platform specific build settings, except when cross-compiling for
+# mobile platforms.
+build --enable_platform_specific_config
+build:android --noenable_platform_specific_config
+build:ios --noenable_platform_specific_config
+
+# By default, build in C++ 17 mode.
+build:android --cxxopt=-std=c++17
+build:android --host_cxxopt=-std=c++17
+build:ios --cxxopt=-std=c++17
+build:ios --host_cxxopt=-std=c++17
+build:linux --cxxopt=-std=c++17
+build:linux --host_cxxopt=-std=c++17
+build:macos --cxxopt=-std=c++17
+build:macos --host_cxxopt=-std=c++17
+build:windows --cxxopt=/std:c++17
+build:windows --host_cxxopt=/std:c++17
diff --git a/AUTHORS b/AUTHORS
index f9a89fe..5e2fc62 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,4 @@
-Google, Inc.
+Google, LLC.
 
 Principal developers:
 
index 368695a..76b4783 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2015-2019 Google LLC. All Rights Reserved.
+# Copyright 2015-2020 Google LLC. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -123,6 +123,7 @@ PUBLIC_HEADERS = [
 cc_library(
     name = "lib_lite",
     srcs = [
+        prefix_dir + "lib/encode.cc",
         prefix_dir + "lib/fst.cc",
         prefix_dir + "lib/properties.cc",
         prefix_dir + "lib/symbol-table-ops.cc",
@@ -170,7 +171,10 @@ cc_library(
 cc_library(
     name = "symbol-table",
     srcs = [prefix_dir + "lib/symbol-table.cc"],
-    hdrs = [prefix_dir + "include/fst/symbol-table.h"],
+    hdrs = [
+        prefix_dir + "include/fst/symbol-table.h",
+        prefix_dir + "include/fst/windows_defs.inc",
+    ],
     copts = ["-Wno-sign-compare"],
     includes = [prefix_dir + "include"],
     deps = [
@@ -183,6 +187,7 @@ cc_library(
     name = "weight",
     srcs = [prefix_dir + "lib/weight.cc"],
     hdrs = [
+        prefix_dir + "include/fst/error-weight.h",
         prefix_dir + "include/fst/expectation-weight.h",
         prefix_dir + "include/fst/float-weight.h",
         prefix_dir + "include/fst/lexicographic-weight.h",
@@ -279,7 +284,7 @@ cc_library(
     }),
     includes = [prefix_dir + "include"],
     deps = select({
-        ":has_absl": ["@com_google_absl//absl/synchronization"],
+        ":has_absl": ["@io_abseil_cpp//absl/synchronization"],
         "//conditions:default": [],
     }),
 )
@@ -291,8 +296,10 @@ cc_test(
     timeout = "short",
     srcs = [
         prefix_dir + "test/fst_test.cc",
+        prefix_dir + "include/fst/test/compactors.h",
         prefix_dir + "include/fst/test/fst_test.h",
     ],
+    includes = [prefix_dir + "include"],
     deps = [":fst"],
 )
 
@@ -357,7 +364,6 @@ cc_library(
         prefix_dir + "include/fst/script/fstscript-decl.h",
         prefix_dir + "include/fst/script/fstscript.h",
         prefix_dir + "include/fst/script/getters.h",
-        prefix_dir + "include/fst/script/register.h",
         prefix_dir + "include/fst/script/script-impl.h",
         prefix_dir + "include/fst/script/stateiterator-class.h",
         prefix_dir + "include/fst/script/text-io.h",
@@ -707,6 +713,7 @@ cc_binary(
     deps = [":fstscript_verify"],
 )
 
+
 # Extension: Fst ARchive a/k/a FAR (extensions/far/)
 
 cc_library(
@@ -740,6 +747,7 @@ cc_library(
     srcs = [prefix_dir + "extensions/far/strings.cc"],
     hdrs = [
         prefix_dir + "include/fst/extensions/far/compile-strings.h",
+        prefix_dir + "include/fst/extensions/far/convert.h",
         prefix_dir + "include/fst/extensions/far/create.h",
         prefix_dir + "include/fst/extensions/far/equal.h",
         prefix_dir + "include/fst/extensions/far/extract.h",
@@ -791,6 +799,7 @@ cc_library(
     )
     for operation in [
         "compilestrings",
+        "convert",
         "create",
         "equal",
         "extract",
@@ -843,7 +852,10 @@ cc_library(
 
 cc_binary(
     name = "pdtcompose",
-    srcs = [prefix_dir + "extensions/pdt/pdtcompose.cc"],
+    srcs = [
+        prefix_dir + "extensions/pdt/pdtcompose.cc",
+        prefix_dir + "extensions/pdt/pdtcompose-main.cc",
+    ],
     linkstatic = static_binary,
     deps = [
         ":fstscript_connect",
@@ -854,7 +866,10 @@ cc_binary(
 [
     cc_binary(
         name = "pdt%s" % operation,
-        srcs = [prefix_dir + "extensions/pdt/pdt%s.cc" % operation],
+        srcs = [
+            prefix_dir + "extensions/pdt/pdt%s.cc" % operation,
+            prefix_dir + "extensions/pdt/pdt%s-main.cc" % operation,
+        ],
         linkstatic = static_binary,
         deps = [":pdtscript"],
     )
@@ -902,7 +917,10 @@ cc_library(
 
 cc_binary(
     name = "mpdtcompose",
-    srcs = [prefix_dir + "extensions/mpdt/mpdtcompose.cc"],
+    srcs = [
+        prefix_dir + "extensions/mpdt/mpdtcompose.cc",
+        prefix_dir + "extensions/mpdt/mpdtcompose-main.cc",
+    ],
     linkstatic = static_binary,
     deps = [
         ":fstscript_connect",
@@ -913,7 +931,10 @@ cc_binary(
 [
     cc_binary(
         name = "mpdt%s" % operation,
-        srcs = [prefix_dir + "extensions/mpdt/mpdt%s.cc" % operation],
+        srcs = [
+            prefix_dir + "extensions/mpdt/mpdt%s.cc" % operation,
+            prefix_dir + "extensions/mpdt/mpdt%s-main.cc" % operation,
+        ],
         linkstatic = static_binary,
         deps = [":mpdtscript"],
     )
@@ -944,4 +965,204 @@ cc_library(
     ],
 )
 
-# TODO: Extensions compact, compress, const, linear, lookahead, python, special
+# Extension: Compact FSTs and FSAs (extensions/compact)
+
+[
+    cc_library(
+        name = "%s-fst" % type,
+        srcs = [
+            prefix_dir + "extensions/compact/%s-fst.cc" % type
+        ],
+        linkstatic = 1,
+        deps = [":fst"],
+    )
+    for type in [
+        "compact16_acceptor",
+        "compact16_string",
+        "compact16_unweighted",
+        "compact16_unweighted_acceptor",
+        "compact16_weighted_string",
+        "compact64_acceptor",
+        "compact64_string",
+        "compact64_unweighted",
+        "compact64_unweighted_acceptor",
+        "compact64_weighted_string",
+        "compact8_acceptor",
+        "compact8_string",
+        "compact8_unweighted",
+        "compact8_unweighted_acceptor",
+        "compact8_weighted_string",
+    ]
+]
+
+# Extension: Compressed FSTs (extensions/compress)
+
+cc_library(
+    name = "compress-fst",
+    hdrs = [
+        prefix_dir + "include/fst/extensions/compress/compress.h",
+        prefix_dir + "include/fst/extensions/compress/elias.h",
+    ],
+    includes = [prefix_dir + "include"],
+    deps = [
+        ":fst",
+    ],
+)
+
+cc_library(
+    name = "compressscript",
+    srcs = [
+        prefix_dir + "extensions/compress/compressscript.cc",
+    ],
+    hdrs = [
+        prefix_dir + "include/fst/extensions/compress/compressscript.h",
+    ],
+    includes = [prefix_dir + "include"],
+    deps = [
+        ":base",
+        ":compress-fst",
+        ":fstscript_base",
+    ],
+)
+
+cc_binary(
+    name = "fstcompress",
+    srcs = [
+        prefix_dir + "extensions/compress/fstcompress.cc",
+        prefix_dir + "extensions/compress/fstcompress-main.cc",
+    ],
+    linkstatic = static_binary,
+    deps = [":compressscript"],
+)
+
+# Extension: Constant FSTs (extensions/const)
+
+[
+    cc_library(
+        name = "const%s-fst" % type,
+        srcs = [
+            prefix_dir + "extensions/const/const%s-fst.cc" % type
+        ],
+        linkstatic = 1,
+        deps = [":fst"],
+    )
+    for type in [
+        "8",
+        "16",
+        "64",
+    ]
+]
+
+# Extension: Linear FSTs (extensions/linear)
+
+cc_library(
+    name = "linear-fst",
+    hdrs = [
+        prefix_dir + "include/fst/extensions/linear/linear-fst-data-builder.h",
+        prefix_dir + "include/fst/extensions/linear/linear-fst-data.h",
+        prefix_dir + "include/fst/extensions/linear/linear-fst.h",
+        prefix_dir + "include/fst/extensions/linear/loglinear-apply.h",
+        prefix_dir + "include/fst/extensions/linear/trie.h",
+    ],
+    srcs = [
+        prefix_dir + "extensions/linear/linear-classifier-fst.cc",
+        prefix_dir + "extensions/linear/linear-tagger-fst.cc",
+    ],
+    linkstatic = 1,
+    deps = [
+        ":fst",
+    ],
+)
+
+cc_library(
+    name = "linearscript",
+    srcs = [
+        prefix_dir + "extensions/linear/linearscript.cc",
+    ],
+    hdrs = [
+        prefix_dir + "include/fst/extensions/linear/linearscript.h",
+    ],
+    includes = [prefix_dir + "include"],
+    deps = [
+        ":base",
+        ":linear-fst",
+        ":fstscript_base",
+    ],
+)
+
+[
+    cc_binary(
+        name = "fst%s" % name,
+        srcs = [
+            prefix_dir + "extensions/linear/fst%s.cc" % name,
+            prefix_dir + "extensions/linear/fst%s-main.cc" % name,
+        ],
+        linkstatic = static_binary,
+        deps = [":linearscript"],
+    )
+    for name in [
+        "linear",
+        "loglinearapply",
+    ]
+]
+
+# Extension: Lookahead FSTs (extensions/lookahead)
+
+[
+    cc_library(
+        name = "%s_lookahead-fst" % type,
+        srcs = [
+            prefix_dir + "extensions/lookahead/%s_lookahead-fst.cc" % type
+        ],
+        linkstatic = 1,
+        deps = [":fst"],
+    )
+    for type in [
+        "arc",
+        "ilabel",
+        "olabel",
+    ]
+]
+
+# Extension: Special FSTs (extensions/special)
+
+[
+    cc_library(
+        name = "%s-fst" % type,
+        srcs = [
+            prefix_dir + "include/fst/extensions/special/%s-fst.h" % type
+        ],
+        hdrs = [
+            prefix_dir + "extensions/special/%s-fst.cc" % type
+        ],
+        linkstatic = 1,
+        deps = [":fst"],
+    )
+    for type in [
+        "phi",
+        "rho",
+        "sigma",
+    ]
+]
+
+cc_binary(
+    name = "fstspecial",
+    srcs = [
+        prefix_dir + "bin/fstconvert.cc",
+        prefix_dir + "bin/fstconvert-main.cc",
+    ],
+    linkstatic = static_binary,
+    deps = [
+        ":fstscript_convert",
+        ":phi-fst",
+        ":rho-fst",
+        ":sigma-fst",
+    ],
+)
+
+# Miscellaneous helper Build rules.
+exports_files([
+    prefix_dir + "extensions/far/build_defs.bzl",
+])
+
+# TODO: Extensions: python
diff --git a/COPYING b/COPYING
index 3633a95..d88414a 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -10,4 +10,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 
-Copyright 2005-2018 Google, Inc.
+Copyright 2005-2020 Google LLC.
index bf3404e..a6f906d 100644 (file)
@@ -1,4 +1,4 @@
 SUBDIRS = src
 ACLOCAL_AMFLAGS = -I m4
 
-EXTRA_DIST = BUILD.bazel WORKSPACE
+EXTRA_DIST = BUILD.bazel WORKSPACE.bazel .bazelrc
index 57b33de..d8cc6f7 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -138,8 +138,8 @@ am__recursive_targets = \
   $(am__extra_recursive_targets)
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
        cscope distdir distdir-am dist dist-all distcheck
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-       $(LISP)config.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+       config.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -345,7 +345,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 SUBDIRS = src
 ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = BUILD.bazel WORKSPACE
+EXTRA_DIST = BUILD.bazel WORKSPACE.bazel .bazelrc
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -605,6 +605,10 @@ dist-xz: distdir
        tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
        $(am__post_remove_distdir)
 
+dist-zstd: distdir
+       tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+       $(am__post_remove_distdir)
+
 dist-tarZ: distdir
        @echo WARNING: "Support for distribution archives compressed with" \
                       "legacy program 'compress' is deprecated." >&2
@@ -647,6 +651,8 @@ distcheck: dist
          eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
        *.zip*) \
          unzip $(distdir).zip ;;\
+       *.tar.zst*) \
+         zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
        esac
        chmod -R a-w $(distdir)
        chmod u+w $(distdir)
@@ -824,18 +830,18 @@ uninstall-am:
        am--refresh check check-am clean clean-cscope clean-generic \
        clean-libtool cscope cscopelist-am ctags ctags-am dist \
        dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-       dist-xz dist-zip distcheck distclean distclean-generic \
-       distclean-hdr distclean-libtool distclean-tags distcleancheck \
-       distdir distuninstallcheck dvi dvi-am html html-am info \
-       info-am install install-am install-data install-data-am \
-       install-dvi install-dvi-am install-exec install-exec-am \
-       install-html install-html-am install-info install-info-am \
-       install-man install-pdf install-pdf-am install-ps \
-       install-ps-am install-strip installcheck installcheck-am \
-       installdirs installdirs-am maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-       uninstall-am
+       dist-xz dist-zip dist-zstd distcheck distclean \
+       distclean-generic distclean-hdr distclean-libtool \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-dvi install-dvi-am \
+       install-exec install-exec-am install-html install-html-am \
+       install-info install-info-am install-man install-pdf \
+       install-pdf-am install-ps install-ps-am install-strip \
+       installcheck installcheck-am installdirs installdirs-am \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags tags-am uninstall uninstall-am
 
 .PRECIOUS: Makefile
 
diff --git a/NEWS b/NEWS
index 375fa63..80bd55c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
 OpenFst: Release 1.7
-   * Compatibility release for Thrax and Pynini improvements (1.7.9)
+   * Adds farconvert (1.8.0)
+   * Migration to C++17 (1.8.0)
+   * Updates Bazel build (1.8.0)
+   * Better handling for empty FARs (1.8.0)
+   * Improves to ExpectationWeight (1.8.0)
+   * Improves display of properties masks in pywrapfst (1.8.0) 
+   * Internal reference-counting/smart pointer improvements (1.8.0)
+   * Deprecates PROJECT_(IN|OUT)PUT in favor of scoped enum ProjectType (1.8.0)
    * TokenType is now a scoped enum (1.7.8)
    * pywrapfst is now Python 3-only (1.7.8)
    * fstproject now has --project_type flag (1.7.8)
diff --git a/README b/README
index 68cf563..2441cce 100644 (file)
--- a/README
+++ b/README
@@ -2,10 +2,11 @@ OpenFst is a library for constructing, combining, optimizing, and searching
 weighted finite-state transducers (FSTs).
 
 REQUIREMENTS:
-  This version is known to work under Linux using g++ (>= 4.9) and OS X using
-  XCode (>= 5). It is expected to work wherever adequate POSIX (dlopen,
-  ssize_t, basename), C99 (snprintf, strtoll, <stdint.h>), and C++11
-  (<unordered_set>, <unordered_map>, <forward_list>) support is available.
+  This version is known to work under Linux using g++ (>= 7) and OS X using
+  XCode (>= 9). It is expected to work wherever adequate POSIX (dlopen,
+  ssize_t, basename), C99 (snprintf, strtoll, <stdint.h>), and C++17
+  (<unordered_set>, <unordered_map>, <forward_list>, constexpr-if) support
+  is available.
 
 INSTALLATION:
   Follow the generic GNU build system instructions in ./INSTALL. We
@@ -56,7 +57,7 @@ USAGE:
 
   To use in your own program, include <fst/fstlib.h> and compile with 
   -I/usr/local/include. The compiler must support C++11 (for g++ add the flag
-  -std=c++11). Link against /usr/local/lib/libfst.so and -ldl. Set your
+  -std=c++17). Link against /usr/local/lib/libfst.so and -ldl. Set your
   LD_LIBRARY_PATH (or equivalent) to contain /usr/local/lib. The linking is,
   by default, dynamic so that the Fst and Arc type DSO extensions can be used
   correctly if desired. Any extensions will be found under /usr/local/lib/fst
diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644 (file)
index e18b187..0000000
--- a/WORKSPACE
+++ /dev/null
@@ -1,15 +0,0 @@
-workspace(name = "openfst")
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-http_archive(
-    name = "com_google_absl",
-    strip_prefix = "abseil-cpp-master",
-    urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
-)
-
-http_archive(
-    name = "com_google_googletest",
-    strip_prefix = "googletest-master",
-    urls = ["https://github.com/google/googletest/archive/master.zip"],
-)
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
new file mode 100644 (file)
index 0000000..2c92a2d
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright 2015-2020 Google LLC. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Bazel (https://bazel.build/) workspace.
+
+workspace(name = "openfst")
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+    name = "io_abseil_cpp",
+    strip_prefix = "abseil-cpp-master",
+    urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
+)
+
+http_archive(
+    name = "com_google_googletest",
+    strip_prefix = "googletest-master",
+    urls = ["https://github.com/google/googletest/archive/master.zip"],
+)
index ad18caf..eab6f94 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.2], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.2])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -118,7 +118,7 @@ AC_SUBST([AR])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -170,7 +170,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -201,7 +201,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -392,7 +392,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -431,7 +431,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -458,7 +460,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -655,7 +657,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -676,7 +678,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -697,7 +699,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -740,7 +742,7 @@ AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -779,7 +781,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -808,7 +810,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -855,7 +857,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1093,7 +1095,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1112,7 +1114,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1193,7 +1195,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1253,7 +1255,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1281,7 +1283,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1300,7 +1302,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/ar-lib b/ar-lib
index 0baa4f6..1e9388e 100755 (executable)
--- a/ar-lib
+++ b/ar-lib
@@ -2,9 +2,9 @@
 # Wrapper for Microsoft lib.exe
 
 me=ar-lib
-scriptversion=2012-03-01.08; # UTC
+scriptversion=2019-07-04.01; # UTC
 
-# Copyright (C) 2010-2018 Free Software Foundation, Inc.
+# Copyright (C) 2010-2020 Free Software Foundation, Inc.
 # Written by Peter Rosin <peda@lysator.liu.se>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
          MINGW*)
            file_conv=mingw
            ;;
-         CYGWIN*)
+         CYGWIN* | MSYS*)
            file_conv=cygwin
            ;;
          *)
@@ -65,7 +65,7 @@ func_file_conv ()
        mingw)
          file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
          ;;
-       cygwin)
+       cygwin | msys)
          file=`cygpath -m "$file" || echo "$file"`
          ;;
        wine)
@@ -224,10 +224,11 @@ elif test -n "$extract"; then
       esac
     done
   else
-    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
-    do
-      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
-    done
+    $AR -NOLOGO -LIST "$archive" | tr -d '\r' | sed -e 's/\\/\\\\/g' \
+      | while read member
+        do
+          $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+        done
   fi
 
 elif test -n "$quick$replace"; then
diff --git a/compile b/compile
index 99e5052..23fcba0 100755 (executable)
--- a/compile
+++ b/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
          MINGW*)
            file_conv=mingw
            ;;
-         CYGWIN*)
+         CYGWIN* | MSYS*)
            file_conv=cygwin
            ;;
          *)
@@ -67,7 +67,7 @@ func_file_conv ()
        mingw/*)
          file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
          ;;
-       cygwin/*)
+       cygwin/* | msys/*)
          file=`cygpath -m "$file" || echo "$file"`
          ;;
        wine/*)
index 6c9c941..fe3d500 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenFst 1.7.9.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.8.0.
 #
 # Report bugs to <help@www.openfst.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='OpenFst'
 PACKAGE_TARNAME='openfst'
-PACKAGE_VERSION='1.7.9'
-PACKAGE_STRING='OpenFst 1.7.9'
+PACKAGE_VERSION='1.8.0'
+PACKAGE_STRING='OpenFst 1.8.0'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -1398,7 +1398,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures OpenFst 1.7.9 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.8.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1469,7 +1469,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.9:";;
+     short | recursive ) echo "Configuration of OpenFst 1.8.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1602,7 +1602,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.9
+OpenFst configure 1.8.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2043,7 +2043,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by OpenFst $as_me 1.7.9, which was
+It was created by OpenFst $as_me 1.8.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2906,7 +2906,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.9'
+ VERSION='1.8.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4598,7 +4598,7 @@ fi
 
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++11 -fno-exceptions"
+CXX="$CXX -std=c++17 -fno-exceptions -Wno-deprecated-declarations"
 
 # Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then :
@@ -17584,7 +17584,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by OpenFst $as_me 1.7.9, which was
+This file was extended by OpenFst $as_me 1.8.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17650,7 +17650,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-OpenFst config.status 1.7.9
+OpenFst config.status 1.8.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18860,7 +18860,9 @@ $as_echo X/"$am_mf" |
     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
index ae727b1..02cbf35 100644 (file)
@@ -1,11 +1,11 @@
-AC_INIT([OpenFst], [1.7.9], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.8.0], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
 AC_PROG_CXX
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++11 -fno-exceptions"
+CXX="$CXX -std=c++17 -fno-exceptions -Wno-deprecated-declarations"
 
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
diff --git a/depcomp b/depcomp
index 65cbf70..6b39162 100755 (executable)
--- a/depcomp
+++ b/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
index 8175c64..20d8b2e 100755 (executable)
@@ -451,7 +451,18 @@ do
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+        # Create $dsttmp read-write so that cp doesn't create it read-only,
+        # which would cause strip to fail.
+        if test -z "$doit"; then
+          : >"$dsttmp" # No need to fork-exec 'touch'.
+        else
+          $doit touch "$dsttmp"
+        fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
diff --git a/missing b/missing
index 625aeb1..8d0eaad 100755 (executable)
--- a/missing
+++ b/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
index 7dbf1c3..7418ba5 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index 991352c..c28c1ee 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index 9cf8484..84098b6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 9476be1..d7ef333 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index dca66c8..6464d22 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index fb3c22f..4fd3093 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 0f4fe5d..302f50d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -75,10 +89,12 @@ int fstcompile_main(int argc, char **argv) {
 
   const std::string dest = argc > 2 && strcmp(argv[2], "-") != 0 ? argv[2] : "";
 
-  s::CompileFst(istrm, source, dest, FLAGS_fst_type, FLAGS_arc_type,
-                isyms.get(), osyms.get(), ssyms.get(), FLAGS_acceptor,
-                FLAGS_keep_isymbols, FLAGS_keep_osymbols,
-                FLAGS_keep_state_numbering, FLAGS_allow_negative_labels);
+  s::CompileFst(
+      istrm, source, dest, FLAGS_fst_type, FLAGS_arc_type, isyms.get(),
+      osyms.get(), ssyms.get(), FLAGS_acceptor,
+      FLAGS_keep_isymbols, FLAGS_keep_osymbols,
+      FLAGS_keep_state_numbering,
+      FLAGS_allow_negative_labels);
 
   return 0;
 }
index 9b758b6..68e3277 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e1de5d7..cb1ba3f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e7aa378..f16f0a4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 436ba35..eaaf900 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 68ce58c..648a07a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2bfacf2..e04a6ee 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index c31a357..3874c03 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a7aa447..1e1aeb6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 331977a..7b80003 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 7902de6..2aef3a8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -54,12 +68,14 @@ int fstdeterminize_main(int argc, char **argv) {
   VectorFstClass ofst(ifst->ArcType());
 
   const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(ifst->WeightType())
-                           : WeightClass(ifst->WeightType(), FLAGS_weight);
+      FLAGS_weight.empty()
+          ? WeightClass::Zero(ifst->WeightType())
+          : WeightClass(ifst->WeightType(), FLAGS_weight);
 
-  const s::DeterminizeOptions opts(FLAGS_delta, weight_threshold, FLAGS_nstate,
-                                   FLAGS_subsequential_label, det_type,
-                                   FLAGS_increment_subsequential_label);
+  const s::DeterminizeOptions opts(
+      FLAGS_delta, weight_threshold, FLAGS_nstate,
+      FLAGS_subsequential_label, det_type,
+      FLAGS_increment_subsequential_label);
 
   s::Determinize(*ifst, &ofst, opts);
 
index 613522b..db3e81d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d0dd4f1..703760f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 6f28c87..a40618c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d439e03..ac022f1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -43,11 +57,13 @@ int fstdisambiguate_main(int argc, char **argv) {
   VectorFstClass ofst(ifst->ArcType());
 
   const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(ifst->WeightType())
-                           : WeightClass(ifst->WeightType(), FLAGS_weight);
+      FLAGS_weight.empty()
+          ? WeightClass::Zero(ifst->WeightType())
+          : WeightClass(ifst->WeightType(), FLAGS_weight);
 
-  const s::DisambiguateOptions opts(FLAGS_delta, weight_threshold, FLAGS_nstate,
-                                    FLAGS_subsequential_label);
+  const s::DisambiguateOptions opts(
+      FLAGS_delta, weight_threshold, FLAGS_nstate,
+      FLAGS_subsequential_label);
 
   s::Disambiguate(*ifst, &ofst, opts);
 
index 9aa13f3..0cd4348 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index b6b163f..769b592 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -96,10 +110,13 @@ int fstdraw_main(int argc, char **argv) {
 
   // "dest" is only used for the name of the file in error messages.
   const std::string dest = out_name.empty() ? "stdout" : out_name;
-  s::Draw(*fst, isyms.get(), osyms.get(), ssyms.get(), FLAGS_acceptor,
-          FLAGS_title, FLAGS_width, FLAGS_height, FLAGS_portrait,
-          FLAGS_vertical, FLAGS_ranksep, FLAGS_nodesep, FLAGS_fontsize,
-          FLAGS_precision, FLAGS_float_format, FLAGS_show_weight_one, ostrm,
+  s::Draw(*fst, isyms.get(), osyms.get(), ssyms.get(),
+          FLAGS_acceptor, FLAGS_title,
+          FLAGS_width, FLAGS_height,
+          FLAGS_portrait, FLAGS_vertical,
+          FLAGS_ranksep, FLAGS_nodesep,
+          FLAGS_fontsize, FLAGS_precision,
+          FLAGS_float_format, FLAGS_show_weight_one, ostrm,
           dest);
 
   return 0;
index fb34c8a..939a181 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 5515405..348beed 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -52,8 +66,8 @@ int fstencode_main(int argc, char **argv) {
     if (!mapper) return 1;
     s::Encode(fst.get(), mapper.get());
   } else {
-    const auto flags =
-        s::GetEncodeFlags(FLAGS_encode_labels, FLAGS_encode_weights);
+    const auto flags = s::GetEncodeFlags(FLAGS_encode_labels,
+                                         FLAGS_encode_weights);
     EncodeMapperClass mapper(fst->ArcType(), flags);
     s::Encode(fst.get(), &mapper);
     if (!mapper.Write(mapper_name)) return 1;
index ade5a11..7b45bbf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 4308da8..2013f72 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -39,7 +53,8 @@ int fstepsnormalize_main(int argc, char **argv) {
 
   VectorFstClass ofst(ifst->ArcType());
 
-  s::EpsNormalize(*ifst, &ofst, s::GetEpsNormalizeType(FLAGS_eps_norm_output));
+  s::EpsNormalize(*ifst, &ofst,
+                  s::GetEpsNormalizeType(FLAGS_eps_norm_output));
 
   return !ofst.Write(out_name);
 }
index b8091d5..5aaa339 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 22e01ae..38c4747 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e1212a0..29b19d2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 4a0bec6..b03fb02 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -63,9 +77,11 @@ int fstequivalent_main(int argc, char **argv) {
                  << FLAGS_select;
       return 1;
     }
-    const RandGenOptions<s::RandArcSelection> opts(ras, FLAGS_max_length);
-    bool result = s::RandEquivalent(*ifst1, *ifst2, FLAGS_npath, opts,
-                                    FLAGS_delta, FLAGS_seed);
+    const RandGenOptions<s::RandArcSelection> opts(
+        ras, FLAGS_max_length);
+    bool result = s::RandEquivalent(*ifst1, *ifst2, FLAGS_npath,
+                                    opts, FLAGS_delta,
+                                    FLAGS_seed);
     if (!result) VLOG(1) << "FSTs are not equivalent";
     return result ? 0 : 2;
   }
index b2d442a..a67acc7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <limits>
 #include <random>
 
index 5d21708..954d01f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -5,6 +19,7 @@
 // and arcs and property values (see properties.h).
 
 #include <cstring>
+#include <ios>
 #include <memory>
 #include <string>
 
@@ -16,6 +31,38 @@ DECLARE_string(info_type);
 DECLARE_bool(test_properties);
 DECLARE_bool(fst_verify);
 
+namespace {
+// Prints info using only the header of the FST with path `in_name`.
+// Returns true on success.
+bool PrintHeaderInfo(const std::string &in_name) {
+  fst::FstHeader header;
+  if (in_name.empty()) {
+    if (!header.Read(std::cin, "stdin")) {
+      LOG(ERROR) << "fstinfo: Unable to read header from stdin";
+      return false;
+    }
+  } else {
+    std::ifstream istrm;
+    istrm.open(in_name, std::ios_base::in | std::ios_base::binary);
+    if (!istrm) {
+      LOG(ERROR) << "fstinfo: Unable to open " << in_name;
+      return false;
+    }
+    if (!header.Read(istrm, in_name)) {
+      LOG(ERROR) << "fstinfo: Unable to read header from " << in_name;
+      return false;
+    }
+    if (!istrm) {
+      LOG(ERROR) << "fstinfo: Unable to close " << in_name;
+      return false;
+    }
+  }
+
+  fst::PrintHeader(std::cout, header);
+  return true;
+}
+}  // namespace
+
 int fstinfo_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
@@ -34,11 +81,15 @@ int fstinfo_main(int argc, char **argv) {
   const std::string in_name =
       (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
 
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
+  if (FLAGS_info_type == "fast") {
+    if (!PrintHeaderInfo(in_name)) return 1;
+  } else {
+    std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+    if (!ifst) return 1;
 
-  s::Info(*ifst, FLAGS_test_properties, FLAGS_arc_filter, FLAGS_info_type,
-          FLAGS_fst_verify);
+    s::Info(*ifst, FLAGS_test_properties, FLAGS_arc_filter,
+            FLAGS_info_type, FLAGS_fst_verify);
+  }
 
   return 0;
 }
index fa2b4c4..fe8f904 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -9,7 +23,15 @@ DEFINE_string(arc_filter, "any",
               "this only affects the counts of (co)accessible states, "
               "connected states, and (strongly) connected components");
 DEFINE_string(info_type, "auto",
-              "Info format: one of \"auto\", \"long\", \"short\"");
+              "Info format: one of \"auto\", \"long\", \"short\", \"fast\".\n"
+              "auto: Equivalent to \"long\" if the FST is an ExpandedFst,"
+              " otherwise \"short\".\n"
+              "long: Print all properties, computing if unknown;"
+              " this may be slow for large FSTs.\n"
+              "short: Print only type and SymbolTable info.\n"
+              "fast: Print only info that is fast to obtain (by reading"
+              " only the file header);" " this is more info than \"short\","
+              " but less than \"long\".");
 DEFINE_bool(test_properties, true,
             "Compute property values (if unknown to FST)");
 DEFINE_bool(fst_verify, true, "Verify FST sanity");
index aa722ef..64501b9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 48b000a..210ec01 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3d00cc0..252ba4c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 3ead13c..3ddde4d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d54a150..32e1e78 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index bb32962..507d878 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 72cc8cc..bf6771b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -56,7 +70,8 @@ int fstmap_main(int argc, char **argv) {
                                        : WeightClass::Zero(ifst->WeightType()));
 
   std::unique_ptr<FstClass> ofst(
-      s::Map(*ifst, map_type, FLAGS_delta, FLAGS_power, weight_param));
+      s::Map(*ifst, map_type, FLAGS_delta,
+             FLAGS_power, weight_param));
 
   return !ofst->Write(out_name);
 }
index 4f1af30..8a4af14 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index cb50711..27a88f7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -47,10 +61,12 @@ int fstminimize_main(int argc, char **argv) {
 
   if (argc > 3) {
     std::unique_ptr<MutableFstClass> fst2(new VectorFstClass(fst1->ArcType()));
-    s::Minimize(fst1.get(), fst2.get(), FLAGS_delta, FLAGS_allow_nondet);
+    s::Minimize(fst1.get(), fst2.get(), FLAGS_delta,
+                FLAGS_allow_nondet);
     if (!fst2->Write(out2_name)) return 1;
   } else {
-    s::Minimize(fst1.get(), nullptr, FLAGS_delta, FLAGS_allow_nondet);
+    s::Minimize(fst1.get(), nullptr, FLAGS_delta,
+                FLAGS_allow_nondet);
   }
 
   return !fst1->Write(out1_name);
index ef602f7..f8b72c9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index c5f905d..a2fbdc0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -92,7 +106,8 @@ int fstprint_main(int argc, char **argv) {
   }
 
   s::Print(*fst, ostrm, dest, isyms.get(), osyms.get(), ssyms.get(),
-           FLAGS_acceptor, FLAGS_show_weight_one, FLAGS_missing_symbol);
+           FLAGS_acceptor, FLAGS_show_weight_one,
+           FLAGS_missing_symbol);
 
   if (isyms && !FLAGS_save_isymbols.empty()) {
     if (!isyms->WriteText(FLAGS_save_isymbols)) return 1;
index 8f42727..a5ad391 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 25a3a71..a52445b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 8daf57c..f306d11 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2bef035..7611884 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -39,10 +53,12 @@ int fstprune_main(int argc, char **argv) {
   if (!fst) return 1;
 
   const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(fst->WeightType())
-                           : WeightClass(fst->WeightType(), FLAGS_weight);
+      FLAGS_weight.empty()
+          ? WeightClass::Zero(fst->WeightType())
+          : WeightClass(fst->WeightType(), FLAGS_weight);
 
-  s::Prune(fst.get(), weight_threshold, FLAGS_nstate, FLAGS_delta);
+  s::Prune(fst.get(), weight_threshold, FLAGS_nstate,
+           FLAGS_delta);
 
   return !fst->Write(out_name);
 }
index 3902f45..b973714 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3ac240e..17a830d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -44,13 +58,16 @@ int fstpush_main(int argc, char **argv) {
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
 
-  const auto flags =
-      s::GetPushFlags(FLAGS_push_weights, FLAGS_push_labels,
-                      FLAGS_remove_total_weight, FLAGS_remove_common_affix);
+  const auto flags = s::GetPushFlags(FLAGS_push_weights,
+                                     FLAGS_push_labels,
+                                     FLAGS_remove_total_weight,
+                                     FLAGS_remove_common_affix);
 
   VectorFstClass ofst(ifst->ArcType());
 
-  s::Push(*ifst, &ofst, flags, s::GetReweightType(FLAGS_to_final), FLAGS_delta);
+  s::Push(*ifst, &ofst, flags,
+          s::GetReweightType(FLAGS_to_final),
+          FLAGS_delta);
 
   return !ofst.Write(out_name);
 }
index c04d38d..5543007 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 95bb786..44a7023 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -56,9 +70,10 @@ int fstrandgen_main(int argc, char **argv) {
   }
 
   s::RandGen(*ifst, &ofst,
-             RandGenOptions<s::RandArcSelection>(ras, FLAGS_max_length,
-                                                 FLAGS_npath, FLAGS_weighted,
-                                                 FLAGS_remove_total_weight),
+             RandGenOptions<s::RandArcSelection>(
+                 ras, FLAGS_max_length,
+                 FLAGS_npath, FLAGS_weighted,
+                 FLAGS_remove_total_weight),
              FLAGS_seed);
 
   return !ofst.Write(out_name);
index 501fbaa..be6809a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <limits>
 #include <random>
 
index 83552af..3a84726 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -62,19 +76,22 @@ int fstrelabel_main(int argc, char **argv) {
   // Relabel with symbol tables.
   const SymbolTableTextOptions opts(FLAGS_allow_negative_labels);
 
-  if (!FLAGS_relabel_isymbols.empty() || !FLAGS_relabel_osymbols.empty()) {
+  if (!FLAGS_relabel_isymbols.empty() ||
+      !FLAGS_relabel_osymbols.empty()) {
     bool attach_new_isymbols = (fst->InputSymbols() != nullptr);
     std::unique_ptr<const SymbolTable> old_isymbols(
-        FLAGS_isymbols.empty() ? nullptr
-                               : SymbolTable::ReadText(FLAGS_isymbols, opts));
+        FLAGS_isymbols.empty()
+            ? nullptr
+            : SymbolTable::ReadText(FLAGS_isymbols, opts));
     const std::unique_ptr<const SymbolTable> relabel_isymbols(
         FLAGS_relabel_isymbols.empty()
             ? nullptr
             : SymbolTable::ReadText(FLAGS_relabel_isymbols, opts));
     bool attach_new_osymbols = (fst->OutputSymbols() != nullptr);
     std::unique_ptr<const SymbolTable> old_osymbols(
-        FLAGS_osymbols.empty() ? nullptr
-                               : SymbolTable::ReadText(FLAGS_osymbols, opts));
+        FLAGS_osymbols.empty()
+            ? nullptr
+            : SymbolTable::ReadText(FLAGS_osymbols, opts));
     const std::unique_ptr<const SymbolTable> relabel_osymbols(
         FLAGS_relabel_osymbols.empty()
             ? nullptr
index fed7a39..6ab5cd2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 59d0960..6da624e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -5,6 +19,7 @@
 // allowing for the definition of FSTs analogous to RTNs.
 
 #include <cstring>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -19,19 +34,6 @@ DECLARE_string(return_arc_labeling);
 DECLARE_int64(return_label);
 DECLARE_bool(epsilon_on_replace);
 
-namespace fst {
-namespace script {
-namespace {
-
-void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
-  for (const auto &pair : *pairs) delete pair.second;
-  pairs->clear();
-}
-
-}  // namespace
-}  // namespace script
-}  // namespace fst
-
 int fstreplace_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::ReplaceLabelType;
@@ -51,49 +53,42 @@ int fstreplace_main(int argc, char **argv) {
     return 1;
   }
 
-  const std::string in_name = argv[1];
   const std::string out_name = argc % 2 == 0 ? argv[argc - 1] : "";
 
-  auto *ifst = FstClass::Read(in_name);
-  if (!ifst) return 1;
-
-  std::vector<std::pair<int64, const FstClass *>> pairs;
-  // Note that if the root label is beyond the range of the underlying FST's
-  // labels, truncation will occur.
-  const auto root = atoll(argv[2]);
-  pairs.emplace_back(root, ifst);
-
-  for (auto i = 3; i < argc - 1; i += 2) {
-    ifst = FstClass::Read(argv[i]);
-    if (!ifst) {
-      s::Cleanup(&pairs);
-      return 1;
-    }
+  std::vector<std::pair<int64, std::unique_ptr<const FstClass>>> pairs;
+  for (auto i = 1; i < argc - 1; i += 2) {
+    std::unique_ptr<const FstClass> ifst(FstClass::Read(argv[i]));
+    if (!ifst) return 1;
     // Note that if the root label is beyond the range of the underlying FST's
     // labels, truncation will occur.
     const auto label = atoll(argv[i + 1]);
-    pairs.emplace_back(label, ifst);
+    pairs.emplace_back(label, std::move(ifst));
   }
 
   ReplaceLabelType call_label_type;
-  if (!s::GetReplaceLabelType(FLAGS_call_arc_labeling, FLAGS_epsilon_on_replace,
+  if (!s::GetReplaceLabelType(FLAGS_call_arc_labeling,
+                              FLAGS_epsilon_on_replace,
                               &call_label_type)) {
     LOG(ERROR) << argv[0] << ": Unknown or unsupported call arc replace "
                << "label type: " << FLAGS_call_arc_labeling;
   }
   ReplaceLabelType return_label_type;
   if (!s::GetReplaceLabelType(FLAGS_return_arc_labeling,
-                              FLAGS_epsilon_on_replace, &return_label_type)) {
+                              FLAGS_epsilon_on_replace,
+                              &return_label_type)) {
     LOG(ERROR) << argv[0] << ": Unknown or unsupported return arc replace "
                << "label type: " << FLAGS_return_arc_labeling;
   }
+  if (pairs.empty()) {
+    LOG(ERROR) << argv[0] << "At least one replace pair must be provided.";
+    return 1;
+  }
+  const auto root = pairs.front().first;
+  const s::ReplaceOptions opts(root, call_label_type, return_label_type,
+                               FLAGS_return_label);
 
-  s::ReplaceOptions opts(root, call_label_type, return_label_type,
-                         FLAGS_return_label);
-
-  VectorFstClass ofst(ifst->ArcType());
-  s::Replace(pairs, &ofst, opts);
-  s::Cleanup(&pairs);
+  VectorFstClass ofst(pairs.back().second->ArcType());
+  s::Replace(s::BorrowPairs(pairs), &ofst, opts);
 
   return !ofst.Write(out_name);
 }
index 7c36046..2795d02 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e4a7227..73ef449 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index cdc10d6..e4b350d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index ad37ff5..09c3d53 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -43,7 +57,8 @@ int fstreweight_main(int argc, char **argv) {
     return 1;
   }
 
-  s::Reweight(fst.get(), potential, s::GetReweightType(FLAGS_to_final));
+  s::Reweight(fst.get(), potential,
+              s::GetReweightType(FLAGS_to_final));
 
   return !fst->Write(out_name);
 }
index 6e2c83c..b196681 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 92aba7a..c6674ff 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -44,8 +58,9 @@ int fstrmepsilon_main(int argc, char **argv) {
   if (!fst) return 1;
 
   const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(fst->WeightType())
-                           : WeightClass(fst->WeightType(), FLAGS_weight);
+      FLAGS_weight.empty()
+          ? WeightClass::Zero(fst->WeightType())
+          : WeightClass(fst->WeightType(), FLAGS_weight);
 
   QueueType queue_type;
   if (!s::GetQueueType(FLAGS_queue_type, &queue_type)) {
@@ -54,8 +69,9 @@ int fstrmepsilon_main(int argc, char **argv) {
     return 1;
   }
 
-  const s::RmEpsilonOptions opts(queue_type, FLAGS_connect, weight_threshold,
-                                 FLAGS_nstate, FLAGS_delta);
+  const s::RmEpsilonOptions opts(queue_type, FLAGS_connect,
+                                 weight_threshold, FLAGS_nstate,
+                                 FLAGS_delta);
 
   s::RmEpsilon(fst.get(), opts);
 
index 192f5c9..c3ef2e5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 945ab87..35454da 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -60,10 +74,12 @@ int fstshortestdistance_main(int argc, char **argv) {
   }
 
   if (FLAGS_reverse) {
-    s::ShortestDistance(*ifst, &distance, FLAGS_reverse, FLAGS_delta);
+    s::ShortestDistance(*ifst, &distance, FLAGS_reverse,
+                        FLAGS_delta);
   } else {
-    const s::ShortestDistanceOptions opts(queue_type, s::ANY_ARC_FILTER,
-                                          FLAGS_nstate, FLAGS_delta);
+    const s::ShortestDistanceOptions opts(queue_type, s::ArcFilterType::ANY,
+                                          FLAGS_nstate,
+                                          FLAGS_delta);
     s::ShortestDistance(*ifst, &distance, opts);
   }
 
index f87e9ad..d51aa31 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index fe06ac0..3ae6ae6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -47,8 +61,9 @@ int fstshortestpath_main(int argc, char **argv) {
   if (!ifst) return 1;
 
   const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(ifst->WeightType())
-                           : WeightClass(ifst->WeightType(), FLAGS_weight);
+      FLAGS_weight.empty()
+          ? WeightClass::Zero(ifst->WeightType())
+          : WeightClass(ifst->WeightType(), FLAGS_weight);
 
   VectorFstClass ofst(ifst->ArcType());
 
@@ -58,9 +73,10 @@ int fstshortestpath_main(int argc, char **argv) {
     return 1;
   }
 
-  const s::ShortestPathOptions opts(queue_type, FLAGS_nshortest, FLAGS_unique,
-                                    FLAGS_delta, weight_threshold,
-                                    FLAGS_nstate);
+  const s::ShortestPathOptions opts(
+      queue_type, FLAGS_nshortest, FLAGS_unique,
+      FLAGS_delta, weight_threshold,
+      FLAGS_nstate);
 
   s::ShortestPath(*ifst, &ofst, opts);
 
index 722897a..88a0174 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 31bd309..d7b5503 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -94,14 +108,16 @@ int fstsymbols_main(int argc, char **argv) {
   using Label = int64;
   if (!FLAGS_relabel_ipairs.empty()) {
     std::vector<std::pair<Label, Label>> ipairs;
-    ReadLabelPairs(FLAGS_relabel_ipairs, &ipairs, FLAGS_allow_negative_labels);
+    ReadLabelPairs(FLAGS_relabel_ipairs, &ipairs,
+                   FLAGS_allow_negative_labels);
     std::unique_ptr<SymbolTable> isyms_relabel(
         RelabelSymbolTable(fst->InputSymbols(), ipairs));
     fst->SetInputSymbols(isyms_relabel.get());
   }
   if (!FLAGS_relabel_opairs.empty()) {
     std::vector<std::pair<Label, Label>> opairs;
-    ReadLabelPairs(FLAGS_relabel_opairs, &opairs, FLAGS_allow_negative_labels);
+    ReadLabelPairs(FLAGS_relabel_opairs, &opairs,
+                   FLAGS_allow_negative_labels);
     std::unique_ptr<SymbolTable> osyms_relabel(
         RelabelSymbolTable(fst->OutputSymbols(), opairs));
     fst->SetOutputSymbols(osyms_relabel.get());
index 62085fe..cc535d2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a25d654..b664a63 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index a0525fc..7a0e2d5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 6be28ae..f88ace4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 68726c7..e7abad7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index bb7f3b0..7468906 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 2aba499..ba6f742 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2720a15..40cc263 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index d14ceed..5e1fde8 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_un
 lib_LTLIBRARIES = libfstcompact.la
 
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 22:0:0
+libfstcompact_la_LDFLAGS = -version-info 23:0:0
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
index 9d4d7b0..ed56736 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -527,7 +527,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_unweighted-fst.la compact8_unweighted_acceptor-fst.la compact8_weighted_string-fst.la compact16_acceptor-fst.la compact16_string-fst.la compact16_unweighted-fst.la compact16_unweighted_acceptor-fst.la compact16_weighted_string-fst.la compact64_acceptor-fst.la compact64_string-fst.la compact64_unweighted-fst.la compact64_unweighted_acceptor-fst.la compact64_weighted_string-fst.la
 lib_LTLIBRARIES = libfstcompact.la
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 22:0:0
+libfstcompact_la_LDFLAGS = -version-info 23:0:0
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact8_string_fst_la_SOURCES = compact8_string-fst.cc
index 43b9afb..d675996 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d6aa141..e846303 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 105f8c8..893221b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 436ddc2..4a855f0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 46214f5..599e9fe 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 012a12b..03d362a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 5a039c4..17c78eb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e37a03f..207cc39 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 6afe73e..f1ea7d3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 65c8570..7f06faa 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index ff0c998..d1ed7a5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e37cdb9..3361641 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 34c4d31..858c5a0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index de6dbf2..5a757c0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 889daf2..e9939a0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index fc049bf..6d024b4 100644 (file)
@@ -13,7 +13,7 @@ endif
 
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compressscript.cc
-libfstcompressscript_la_LDFLAGS = -version-info 22:0:0
+libfstcompressscript_la_LDFLAGS = -version-info 23:0:0
 libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
                                  ../../lib/libfst.la \
                                  -lm $(DL_LIBS)
index 54834b1..77f1735 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -370,7 +370,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 
 @HAVE_BIN_TRUE@fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_SOURCES = compressscript.cc
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 23:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                                 ../../lib/libfst.la \
 @HAVE_SCRIPT_TRUE@                                 -lm $(DL_LIBS)
index 7174824..197b101 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 4062ebb..a7dcdd6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 14de7ac..c3b214e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e90a251..5173b3f 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 22:0:0
+libfstconst_la_LDFLAGS = -version-info 23:0:0
 
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
index 83bdd2d..6ac1efb 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -371,7 +371,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 22:0:0
+libfstconst_la_LDFLAGS = -version-info 23:0:0
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
 const16_fst_la_SOURCES = const16-fst.cc
index dfc8cfe..6b6a1d3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 63fb7b1..b1f996c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3bc2a53..25d0d9c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index ccb406c..5358334 100644 (file)
@@ -1,5 +1,7 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 
+EXTRA_DIST = build_defs.bzl
+
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstfar.la libfstfarscript.la
 else
@@ -7,27 +9,29 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 22:0:0
+libfstfar_la_LDFLAGS = -version-info 23:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 if HAVE_SCRIPT
 libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
                              strings.cc sttable.cc stlist.cc
-libfstfarscript_la_LDFLAGS = -version-info 22:0:0
+libfstfarscript_la_LDFLAGS = -version-info 23:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
 endif
 
 if HAVE_BIN
-bin_PROGRAMS = farcompilestrings farcreate farequal farextract farinfo \
-    farisomorphic farprintstrings
+bin_PROGRAMS = farcompilestrings farconvert farcreate farequal farextract \
+    farinfo farisomorphic farprintstrings
 
 LDADD = libfstfarscript.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
 
 farcompilestrings_SOURCES = farcompilestrings.cc farcompilestrings-main.cc
 
+farconvert_SOURCES = farconvert.cc farconvert-main.cc
+
 farcreate_SOURCES = farcreate.cc farcreate-main.cc
 
 farequal_SOURCES = farequal.cc farequal-main.cc
index 0658e1e..49ea4d3 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -90,9 +90,10 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @HAVE_BIN_TRUE@bin_PROGRAMS = farcompilestrings$(EXEEXT) \
-@HAVE_BIN_TRUE@        farcreate$(EXEEXT) farequal$(EXEEXT) \
-@HAVE_BIN_TRUE@        farextract$(EXEEXT) farinfo$(EXEEXT) \
-@HAVE_BIN_TRUE@        farisomorphic$(EXEEXT) farprintstrings$(EXEEXT)
+@HAVE_BIN_TRUE@        farconvert$(EXEEXT) farcreate$(EXEEXT) \
+@HAVE_BIN_TRUE@        farequal$(EXEEXT) farextract$(EXEEXT) \
+@HAVE_BIN_TRUE@        farinfo$(EXEEXT) farisomorphic$(EXEEXT) \
+@HAVE_BIN_TRUE@        farprintstrings$(EXEEXT)
 subdir = src/extensions/far
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_devel.m4 \
@@ -174,6 +175,14 @@ farcompilestrings_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farcompilestrings_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
+am__farconvert_SOURCES_DIST = farconvert.cc farconvert-main.cc
+@HAVE_BIN_TRUE@am_farconvert_OBJECTS = farconvert.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farconvert-main.$(OBJEXT)
+farconvert_OBJECTS = $(am_farconvert_OBJECTS)
+farconvert_LDADD = $(LDADD)
+@HAVE_BIN_TRUE@farconvert_DEPENDENCIES = libfstfarscript.la \
+@HAVE_BIN_TRUE@        ../../script/libfstscript.la \
+@HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
 am__farcreate_SOURCES_DIST = farcreate.cc farcreate-main.cc
 @HAVE_BIN_TRUE@am_farcreate_OBJECTS = farcreate.$(OBJEXT) \
 @HAVE_BIN_TRUE@        farcreate-main.$(OBJEXT)
@@ -241,12 +250,13 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__maybe_remake_depfiles = depfiles
 am__depfiles_remade = ./$(DEPDIR)/far-class.Plo \
        ./$(DEPDIR)/farcompilestrings-main.Po \
-       ./$(DEPDIR)/farcompilestrings.Po ./$(DEPDIR)/farcreate-main.Po \
-       ./$(DEPDIR)/farcreate.Po ./$(DEPDIR)/farequal-main.Po \
-       ./$(DEPDIR)/farequal.Po ./$(DEPDIR)/farextract-main.Po \
-       ./$(DEPDIR)/farextract.Po ./$(DEPDIR)/farinfo-main.Po \
-       ./$(DEPDIR)/farinfo.Po ./$(DEPDIR)/farisomorphic-main.Po \
-       ./$(DEPDIR)/farisomorphic.Po \
+       ./$(DEPDIR)/farcompilestrings.Po \
+       ./$(DEPDIR)/farconvert-main.Po ./$(DEPDIR)/farconvert.Po \
+       ./$(DEPDIR)/farcreate-main.Po ./$(DEPDIR)/farcreate.Po \
+       ./$(DEPDIR)/farequal-main.Po ./$(DEPDIR)/farequal.Po \
+       ./$(DEPDIR)/farextract-main.Po ./$(DEPDIR)/farextract.Po \
+       ./$(DEPDIR)/farinfo-main.Po ./$(DEPDIR)/farinfo.Po \
+       ./$(DEPDIR)/farisomorphic-main.Po ./$(DEPDIR)/farisomorphic.Po \
        ./$(DEPDIR)/farprintstrings-main.Po \
        ./$(DEPDIR)/farprintstrings.Po ./$(DEPDIR)/farscript.Plo \
        ./$(DEPDIR)/getters.Plo ./$(DEPDIR)/script-impl.Plo \
@@ -272,15 +282,16 @@ am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
 am__v_CXXLD_1 = 
 SOURCES = $(libfstfar_la_SOURCES) $(libfstfarscript_la_SOURCES) \
-       $(farcompilestrings_SOURCES) $(farcreate_SOURCES) \
-       $(farequal_SOURCES) $(farextract_SOURCES) $(farinfo_SOURCES) \
-       $(farisomorphic_SOURCES) $(farprintstrings_SOURCES)
+       $(farcompilestrings_SOURCES) $(farconvert_SOURCES) \
+       $(farcreate_SOURCES) $(farequal_SOURCES) $(farextract_SOURCES) \
+       $(farinfo_SOURCES) $(farisomorphic_SOURCES) \
+       $(farprintstrings_SOURCES)
 DIST_SOURCES = $(libfstfar_la_SOURCES) \
        $(am__libfstfarscript_la_SOURCES_DIST) \
        $(am__farcompilestrings_SOURCES_DIST) \
-       $(am__farcreate_SOURCES_DIST) $(am__farequal_SOURCES_DIST) \
-       $(am__farextract_SOURCES_DIST) $(am__farinfo_SOURCES_DIST) \
-       $(am__farisomorphic_SOURCES_DIST) \
+       $(am__farconvert_SOURCES_DIST) $(am__farcreate_SOURCES_DIST) \
+       $(am__farequal_SOURCES_DIST) $(am__farextract_SOURCES_DIST) \
+       $(am__farinfo_SOURCES_DIST) $(am__farisomorphic_SOURCES_DIST) \
        $(am__farprintstrings_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -446,15 +457,16 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
+EXTRA_DIST = build_defs.bzl
 @HAVE_SCRIPT_FALSE@lib_LTLIBRARIES = libfstfar.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstfar.la libfstfarscript.la
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 22:0:0
+libfstfar_la_LDFLAGS = -version-info 23:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
 @HAVE_SCRIPT_TRUE@                             strings.cc sttable.cc stlist.cc
 
-@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 23:0:0
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_LIBADD = \
 @HAVE_SCRIPT_TRUE@    libfstfar.la ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
@@ -463,6 +475,7 @@ libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 @HAVE_BIN_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
 
 @HAVE_BIN_TRUE@farcompilestrings_SOURCES = farcompilestrings.cc farcompilestrings-main.cc
+@HAVE_BIN_TRUE@farconvert_SOURCES = farconvert.cc farconvert-main.cc
 @HAVE_BIN_TRUE@farcreate_SOURCES = farcreate.cc farcreate-main.cc
 @HAVE_BIN_TRUE@farequal_SOURCES = farequal.cc farequal-main.cc
 @HAVE_BIN_TRUE@farextract_SOURCES = farextract.cc farextract-main.cc
@@ -597,6 +610,10 @@ farcompilestrings$(EXEEXT): $(farcompilestrings_OBJECTS) $(farcompilestrings_DEP
        @rm -f farcompilestrings$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(farcompilestrings_OBJECTS) $(farcompilestrings_LDADD) $(LIBS)
 
+farconvert$(EXEEXT): $(farconvert_OBJECTS) $(farconvert_DEPENDENCIES) $(EXTRA_farconvert_DEPENDENCIES) 
+       @rm -f farconvert$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(farconvert_OBJECTS) $(farconvert_LDADD) $(LIBS)
+
 farcreate$(EXEEXT): $(farcreate_OBJECTS) $(farcreate_DEPENDENCIES) $(EXTRA_farcreate_DEPENDENCIES) 
        @rm -f farcreate$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(farcreate_OBJECTS) $(farcreate_LDADD) $(LIBS)
@@ -630,6 +647,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/far-class.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings-main.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farconvert-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farconvert.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate-main.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal-main.Po@am__quote@ # am--include-marker
@@ -818,6 +837,8 @@ distclean: distclean-am
                -rm -f ./$(DEPDIR)/far-class.Plo
        -rm -f ./$(DEPDIR)/farcompilestrings-main.Po
        -rm -f ./$(DEPDIR)/farcompilestrings.Po
+       -rm -f ./$(DEPDIR)/farconvert-main.Po
+       -rm -f ./$(DEPDIR)/farconvert.Po
        -rm -f ./$(DEPDIR)/farcreate-main.Po
        -rm -f ./$(DEPDIR)/farcreate.Po
        -rm -f ./$(DEPDIR)/farequal-main.Po
@@ -884,6 +905,8 @@ maintainer-clean: maintainer-clean-am
                -rm -f ./$(DEPDIR)/far-class.Plo
        -rm -f ./$(DEPDIR)/farcompilestrings-main.Po
        -rm -f ./$(DEPDIR)/farcompilestrings.Po
+       -rm -f ./$(DEPDIR)/farconvert-main.Po
+       -rm -f ./$(DEPDIR)/farconvert.Po
        -rm -f ./$(DEPDIR)/farcreate-main.Po
        -rm -f ./$(DEPDIR)/farcreate.Po
        -rm -f ./$(DEPDIR)/farequal-main.Po
diff --git a/src/extensions/far/build_defs.bzl b/src/extensions/far/build_defs.bzl
new file mode 100644 (file)
index 0000000..e69d68f
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""Helper library to define BUILD rules for FAR manipulation."""
+
+def convert_far_types(name, far_in, far_out, far_type = None, fst_type = None, **kwds):
+    """Converts the FAR type and/or FST types in a FAR, writing a new FAR.
+
+    Args:
+      name: The BUILD rule name.
+      far_in: The input FAR file.
+      far_out: The output FAR file with converted FST types.
+      far_type: An optional string specifying the desired type of the FAR in far_out.
+                If None, the input FAR's type will be used.
+      fst_type: An optional string specifying the desired type of the FSTs in far_out.
+                If None, each FST will retain its input type.
+      **kwds: Attributes common to all BUILD rules, e.g., testonly, visibility.
+    """
+
+    farconvert_rule = "@org_openfst//:farconvert"
+    farconvert_cmd = "$(location %s) " % farconvert_rule
+    if not far_type and not fst_type:
+        fail("No-op conversion for FAR %s." % far_in)
+    if far_type:
+        farconvert_cmd += " --far_type=%s" % far_type
+    if fst_type:
+        farconvert_cmd += " --fst_type=%s" % fst_type
+    farconvert_cmd += " $(location %s)" % far_in
+    farconvert_cmd += " $(location %s)" % far_out
+
+    native.genrule(
+        name = name,
+        srcs = [far_in],
+        exec_tools = [farconvert_rule],
+        outs = [far_out],
+        cmd = farconvert_cmd,
+        message = "Converting FST type in FAR %s ==> %s" % (far_in, far_out),
+        **kwds
+    )
index 8fd8bd7..16d8f11 100644 (file)
@@ -1,9 +1,24 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 #include <fst/extensions/far/far-class.h>
 
 #include <fst/extensions/far/script-impl.h>
+#include <fst/arc.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
@@ -11,46 +26,56 @@ namespace script {
 
 // FarReaderClass.
 
-FarReaderClass *FarReaderClass::Open(const std::string &source) {
+std::unique_ptr<FarReaderClass> FarReaderClass::Open(
+    const std::string &source) {
   const std::vector<std::string> sources{source};
   return FarReaderClass::Open(sources);
 }
 
-FarReaderClass *FarReaderClass::Open(const std::vector<std::string> &sources) {
+std::unique_ptr<FarReaderClass> FarReaderClass::Open(
+    const std::vector<std::string> &sources) {
   if (sources.empty()) {
     LOG(ERROR) << "FarReaderClass::Open: No files specified";
     return nullptr;
   }
-  const auto arc_type = LoadArcTypeFromFar(sources.front());
-  if (arc_type.empty()) return nullptr;
+  auto arc_type = LoadArcTypeFromFar(sources.front());
+  if (arc_type.empty()) {
+    LOG(ERROR) << "FarReaderClass::Open: File could not be opened: "
+               << sources.front();
+    return nullptr;
+  }
+  // TODO(jrosenstock): What if we have an empty FAR for the first one,
+  // then non-empty?  We need to check all input FARs.
   OpenFarReaderClassArgs args(sources);
   args.retval = nullptr;
   Apply<Operation<OpenFarReaderClassArgs>>("OpenFarReaderClass", arc_type,
                                            &args);
-  return args.retval;
+  return std::move(args.retval);
 }
 
 REGISTER_FST_OPERATION(OpenFarReaderClass, StdArc, OpenFarReaderClassArgs);
 REGISTER_FST_OPERATION(OpenFarReaderClass, LogArc, OpenFarReaderClassArgs);
 REGISTER_FST_OPERATION(OpenFarReaderClass, Log64Arc, OpenFarReaderClassArgs);
+REGISTER_FST_OPERATION(OpenFarReaderClass, ErrorArc, OpenFarReaderClassArgs);
 
 // FarWriterClass.
 
-FarWriterClass *FarWriterClass::Create(const std::string &source,
-                                       const std::string &arc_type,
-                                       FarType type) {
+std::unique_ptr<FarWriterClass> FarWriterClass::Create(
+    const std::string &source, const std::string &arc_type, FarType type) {
   CreateFarWriterClassInnerArgs iargs(source, type);
   CreateFarWriterClassArgs args(iargs);
   args.retval = nullptr;
   Apply<Operation<CreateFarWriterClassArgs>>("CreateFarWriterClass", arc_type,
                                              &args);
-  return args.retval;
+  return std::move(args.retval);
 }
 
 REGISTER_FST_OPERATION(CreateFarWriterClass, StdArc, CreateFarWriterClassArgs);
 REGISTER_FST_OPERATION(CreateFarWriterClass, LogArc, CreateFarWriterClassArgs);
 REGISTER_FST_OPERATION(CreateFarWriterClass, Log64Arc,
                        CreateFarWriterClassArgs);
+REGISTER_FST_OPERATION(CreateFarWriterClass, ErrorArc,
+                       CreateFarWriterClassArgs);
 
 }  // namespace script
 }  // namespace fst
index 8f752c5..f5f7c2d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -48,13 +62,12 @@ int farcompilestrings_main(int argc, char **argv) {
   } else {
     for (int i = 1; i < argc - 1; ++i)
       in_sources.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
-  }
-  if (in_sources.empty()) {
-    // argc == 1 || argc == 2.  This cleverly handles both the no-file case
-    // and the one (input) file case together.
-    // TODO(jrosenstock): This probably shouldn't happen for the
-    // --file_list_input case.
-    in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
+    if (in_sources.empty()) {
+      // argc == 1 || argc == 2. This cleverly handles both the no-file case
+      // and the one (input) file case together.
+      in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1]
+                                                                  : "");
+    }
   }
 
   // argc <= 2 means the file (if any) is an input file, so write to stdout.
@@ -79,7 +92,12 @@ int farcompilestrings_main(int argc, char **argv) {
     return 1;
   }
 
-  s::FarCompileStrings(in_sources, out_source, FLAGS_arc_type, FLAGS_fst_type,
+  // Empty fst_type means vector for farcompilestrings, but "input FST type"
+  // for farconvert.
+  const std::string fst_type =
+      FLAGS_fst_type.empty() ? "vector" : FLAGS_fst_type;
+
+  s::FarCompileStrings(in_sources, out_source, FLAGS_arc_type, fst_type,
                        far_type, FLAGS_generate_keys, entry_type, token_type,
                        FLAGS_symbols, FLAGS_unknown_symbol, FLAGS_keep_symbols,
                        FLAGS_initial_symbols, FLAGS_allow_negative_labels,
index 79aebf7..7129216 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 
 DEFINE_string(key_prefix, "", "Prefix to append to keys");
@@ -13,7 +27,7 @@ DEFINE_string(arc_type, "standard", "Output arc type");
 DEFINE_string(entry_type, "line",
               "Entry type: one of : "
               "\"file\" (one FST per file), \"line\" (one FST per line)");
-DEFINE_string(fst_type, "vector", "Output FST type");
+DEFINE_string(fst_type, "", "Output FST type");
 DEFINE_string(token_type, "symbol",
               "Token type: one of : "
               "\"symbol\", \"byte\", \"utf8\"");
diff --git a/src/extensions/far/farconvert-main.cc b/src/extensions/far/farconvert-main.cc
new file mode 100644 (file)
index 0000000..d9211a1
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Converts FST and container type of FARs.
+
+#include <cstring>
+#include <string>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(far_type);
+DECLARE_string(fst_type);
+
+int farconvert_main(int argc, char *argv[]) {
+  namespace s = fst::script;
+
+  std::string usage = "Converts FST and container types.\n\n Usage:";
+  usage += argv[0];
+  usage += " [in.far [out.far]]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  // 0 file args means read from stdin and write to stdout.
+  // 1 file arg means read from in.far and write to stdout.
+  // Only STList can be written to stdout; there will be
+  // an error in Write() when another format is used.
+  const std::string in_far =
+      argc > 1 && std::strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  const std::string out_far =
+      argc > 2 && std::strcmp(argv[2], "-") != 0 ? argv[2] : "";
+
+  fst::FarType far_type;
+  if (!s::GetFarType(FLAGS_far_type, &far_type)) {
+    LOG(ERROR) << "Unknown --far_type " << FLAGS_far_type;
+    return 1;
+  }
+
+  // We use a different meaning of far_type. DEFAULT means "same as input",
+  // so snoop the input far_type.
+  if (far_type == fst::FarType::DEFAULT) {
+    fst::FarHeader hdr;
+    if (!hdr.Read(in_far)) {
+      LOG(ERROR) << "Couldn't open " << in_far;
+      return 1;
+    }
+    // GetFarType returns STLIST for stdin, regardless of the actual FAR type.
+    // If the input actually has another type, it Open() will fail later.
+    if (!s::GetFarType(hdr.FarType(), &far_type)) {
+      LOG(ERROR) << "Failed to retrieve archive type from " << in_far;
+      return 1;
+    }
+  }
+
+  // LoadArcTypeFromFar returns arc_type=="standard" for stdin. As above
+  // with FarType, Open() will fail later if it actually has a different type.
+  const std::string arc_type = s::LoadArcTypeFromFar(in_far);
+  if (arc_type.empty()) {
+    LOG(ERROR) << "Could not determine arc type for " << in_far;
+    return 1;
+  }
+
+  // Empty fst_type means use input fst type for each fst individually.
+  s::FarConvert(in_far, out_far, arc_type, FLAGS_fst_type, far_type);
+
+  return 0;
+}
diff --git a/src/extensions/far/farconvert.cc b/src/extensions/far/farconvert.cc
new file mode 100644 (file)
index 0000000..afbcd0b
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include <fst/flags.h>
+
+DEFINE_string(fst_type, "",
+              "FST type to convert to. "
+              "If empty, each FST's type is unchanged");
+DEFINE_string(far_type, "default",
+              "FAR file format type: one of: \"default\", \"fst\", "
+              "\"stlist\", \"sttable\". "
+              "\"default\" means use type of input FAR.");
+
+int farconvert_main(int argc, char **argv);
+
+int main(int argc, char **argv) { return farconvert_main(argc, argv); }
index 60d50d7..b313945 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -9,6 +23,7 @@
 #include <fst/flags.h>
 #include <fst/extensions/far/farscript.h>
 #include <fst/extensions/far/getters.h>
+#include <fst/arc.h>
 #include <fstream>
 
 DECLARE_string(key_prefix);
@@ -39,21 +54,23 @@ int farcreate_main(int argc, char **argv) {
   } else {
     for (int i = 1; i < argc - 1; ++i)
       in_sources.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
-  }
-  if (in_sources.empty()) {
-    // argc == 1 || argc == 2.  This cleverly handles both the no-file case
-    // and the one (input) file case together.
-    // TODO(jrosenstock): This probably shouldn't happen for the
-    // --file_list_input case.
-    in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
+    if (in_sources.empty()) {
+      // argc == 1 || argc == 2. This cleverly handles both the no-file case
+      // and the one (input) file case together.
+      in_sources.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1]
+                                                                  : "");
+    }
   }
 
   // argc <= 2 means the file (if any) is an input file, so write to stdout.
   const std::string out_source =
       argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
 
-  const auto arc_type = s::LoadArcTypeFromFst(in_sources[0]);
-  if (arc_type.empty()) return 1;
+  std::string arc_type = fst::ErrorArc::Type();
+  if (!in_sources.empty()) {
+    arc_type = s::LoadArcTypeFromFst(in_sources[0]);
+    if (arc_type.empty()) return 1;
+  }
 
   fst::FarType far_type;
   if (!s::GetFarType(FLAGS_far_type, &far_type)) {
index 284e5d5..0db53c5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 
 DEFINE_string(key_prefix, "", "Prefix to append to keys");
index 6e49da8..528ff87 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 39e1cfb..de03019 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 #include <fst/weight.h>
 
index 01778bf..1627cbc 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index eb9dd3e..5752a22 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 
 DEFINE_string(filename_prefix, "", "Prefix to append to filenames");
index 3c39366..d96c17e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index ae9ee29..b765edb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 
 DEFINE_string(begin_key, "",
index 614a94a..4748bd4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 1ed29ec..2b6e4ed 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 #include <fst/weight.h>
 
index dabfec8..ec3e102 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 137ad4a..8800cbf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/flags.h>
 
 DEFINE_string(filename_prefix, "", "Prefix to append to filenames");
index be7216c..357326e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -7,8 +21,13 @@
 #include <fst/extensions/far/farscript.h>
 
 #include <fst/extensions/far/far.h>
+#include <fst/arc.h>
 #include <fst/script/script-impl.h>
 
+#define REGISTER_FST_OPERATION_4ARCS(Op, ArgPack) \
+  REGISTER_FST_OPERATION_3ARCS(Op, ArgPack);      \
+  REGISTER_FST_OPERATION(Op, ErrorArc, ArgPack)
+
 namespace fst {
 namespace script {
 
@@ -22,36 +41,45 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
                        bool initial_symbols, bool allow_negative_labels,
                        const std::string &key_prefix,
                        const std::string &key_suffix) {
-  FarCompileStringsArgs args(in_sources, out_source, fst_type, far_type,
+  FarCompileStringsArgs args{in_sources, out_source, fst_type, far_type,
                              generate_keys, fet, tt, symbols_source,
                              unknown_symbol, keep_symbols, initial_symbols,
-                             allow_negative_labels, key_prefix, key_suffix);
+                             allow_negative_labels, key_prefix, key_suffix};
   Apply<Operation<FarCompileStringsArgs>>("FarCompileStrings", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarCompileStrings, FarCompileStringsArgs);
+REGISTER_FST_OPERATION_4ARCS(FarCompileStrings, FarCompileStringsArgs);
+
+void FarConvert(const std::string &in_source, const std::string &out_source,
+                const std::string &arc_type, const std::string &fst_type,
+                const FarType &far_type) {
+  FarConvertArgs args{in_source, out_source, fst_type, far_type};
+  Apply<Operation<FarConvertArgs>>("FarConvert", arc_type, &args);
+}
+
+REGISTER_FST_OPERATION_4ARCS(FarConvert, FarConvertArgs);
 
 void FarCreate(const std::vector<std::string> &in_sources,
                const std::string &out_source, const std::string &arc_type,
                const int32 generate_keys, const FarType &far_type,
                const std::string &key_prefix, const std::string &key_suffix) {
-  FarCreateArgs args(in_sources, out_source, generate_keys, far_type,
-                     key_prefix, key_suffix);
+  FarCreateArgs args{in_sources, out_source, generate_keys, far_type,
+                     key_prefix, key_suffix};
   Apply<Operation<FarCreateArgs>>("FarCreate", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarCreate, FarCreateArgs);
+REGISTER_FST_OPERATION_4ARCS(FarCreate, FarCreateArgs);
 
 bool FarEqual(const std::string &source1, const std::string &source2,
               const std::string &arc_type, float delta,
               const std::string &begin_key, const std::string &end_key) {
-  FarEqualInnerArgs args(source1, source2, delta, begin_key, end_key);
+  FarEqualInnerArgs args{source1, source2, delta, begin_key, end_key};
   FarEqualArgs args_with_retval(args);
   Apply<Operation<FarEqualArgs>>("FarEqual", arc_type, &args_with_retval);
   return args_with_retval.retval;
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarEqual, FarEqualArgs);
+REGISTER_FST_OPERATION_4ARCS(FarEqual, FarEqualArgs);
 
 void FarExtract(const std::vector<std::string> &isources,
                 const std::string &arc_type, int32 generate_sources,
@@ -59,42 +87,42 @@ void FarExtract(const std::vector<std::string> &isources,
                 const std::string &range_delimiter,
                 const std::string &source_prefix,
                 const std::string &source_suffix) {
-  FarExtractArgs args(isources, generate_sources, keys, key_separator,
-                      range_delimiter, source_prefix, source_suffix);
+  FarExtractArgs args{isources, generate_sources, keys, key_separator,
+                      range_delimiter, source_prefix, source_suffix};
   Apply<Operation<FarExtractArgs>>("FarExtract", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarExtract, FarExtractArgs);
+REGISTER_FST_OPERATION_4ARCS(FarExtract, FarExtractArgs);
 
 void FarInfo(const std::vector<std::string> &sources,
              const std::string &arc_type, const std::string &begin_key,
              const std::string &end_key, bool list_fsts) {
-  FarInfoArgs args(sources, begin_key, end_key, list_fsts);
+  FarInfoArgs args{sources, begin_key, end_key, list_fsts};
   Apply<Operation<FarInfoArgs>>("FarInfo", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarInfo, FarInfoArgs);
+REGISTER_FST_OPERATION_4ARCS(FarInfo, FarInfoArgs);
 
 void GetFarInfo(const std::vector<std::string> &sources,
                 const std::string &arc_type, const std::string &begin_key,
                 const std::string &end_key, bool list_fsts, FarInfoData *data) {
-  GetFarInfoArgs args(sources, begin_key, end_key, list_fsts, data);
+  GetFarInfoArgs args{sources, begin_key, end_key, list_fsts, data};
   Apply<Operation<GetFarInfoArgs>>("GetFarInfo", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(GetFarInfo, GetFarInfoArgs);
+REGISTER_FST_OPERATION_4ARCS(GetFarInfo, GetFarInfoArgs);
 
 bool FarIsomorphic(const std::string &source1, const std::string &source2,
                    const std::string &arc_type, float delta,
                    const std::string &begin_key, const std::string &end_key) {
-  FarIsomorphicInnerArgs args(source1, source2, delta, begin_key, end_key);
+  FarIsomorphicInnerArgs args{source1, source2, delta, begin_key, end_key};
   FarIsomorphicArgs args_with_retval(args);
   Apply<Operation<FarIsomorphicArgs>>("FarIsomorphic", arc_type,
                                       &args_with_retval);
   return args_with_retval.retval;
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarIsomorphic, FarIsomorphicArgs);
+REGISTER_FST_OPERATION_4ARCS(FarIsomorphic, FarIsomorphicArgs);
 
 void FarPrintStrings(const std::vector<std::string> &isources,
                      const std::string &arc_type, const FarEntryType entry_type,
@@ -104,14 +132,14 @@ void FarPrintStrings(const std::vector<std::string> &isources,
                      bool initial_symbols, const int32 generate_sources,
                      const std::string &source_prefix,
                      const std::string &source_suffix) {
-  FarPrintStringsArgs args(isources, entry_type, token_type, begin_key, end_key,
+  FarPrintStringsArgs args{isources, entry_type, token_type, begin_key, end_key,
                            print_key, print_weight, symbols_source,
                            initial_symbols, generate_sources, source_prefix,
-                           source_suffix);
+                           source_suffix};
   Apply<Operation<FarPrintStringsArgs>>("FarPrintStrings", arc_type, &args);
 }
 
-REGISTER_FST_OPERATION_3ARCS(FarPrintStrings, FarPrintStringsArgs);
+REGISTER_FST_OPERATION_4ARCS(FarPrintStrings, FarPrintStringsArgs);
 
 }  // namespace script
 }  // namespace fst
index 46b9392..5307e72 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 27d49b6..b31d95e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -20,12 +34,7 @@ std::string LoadArcTypeFromFar(const std::string &far_source) {
     LOG(ERROR) << "Error reading FAR: " << far_source;
     return "";
   }
-  std::string atype = hdr.ArcType();
-  if (atype == "unknown") {
-    LOG(ERROR) << "Empty FST archive: " << far_source;
-    return "";
-  }
-  return atype;
+  return hdr.ArcType();
 }
 
 std::string LoadArcTypeFromFst(const std::string &fst_source) {
index b141d2c..56ba669 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index c1ae0c7..7ec949c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 030f39b..24e8fdc 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e8c9053..0619c75 100644 (file)
@@ -15,7 +15,7 @@ if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstlinearscript.la
 
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 22:0:0
+libfstlinearscript_la_LDFLAGS = -version-info 23:0:0
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 endif
 
index 18503e4..c5d48d5 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -396,7 +396,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@fstloglinearapply_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstlinearscript.la
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 23:0:0
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
 linear_tagger_fst_la_SOURCES = linear-tagger-fst.cc
index ac85cb4..29331dd 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a0090de..5e68c19 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 58f8dca..0d68363 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 4a8ac68..1e3389c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 075a875..a4cd944 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3c72bbd..17a44ec 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f237c4a..c524c93 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a5687fd..0920be7 100644 (file)
@@ -9,7 +9,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
-libfstlookahead_la_LDFLAGS = -version-info 22:0:0
+libfstlookahead_la_LDFLAGS = -version-info 23:0:0
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
index 5675c96..fe9001b 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -382,7 +382,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
 
-libfstlookahead_la_LDFLAGS = -version-info 22:0:0
+libfstlookahead_la_LDFLAGS = -version-info 23:0:0
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
 ilabel_lookahead_fst_la_SOURCES = ilabel_lookahead-fst.cc
index 63b16e4..0761653 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 5b7fa69..e7d6c0c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 9d3067f..270b652 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f6f12b7..44fdf60 100644 (file)
@@ -20,7 +20,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 22:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 23:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index b7119cf..b284cb1 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@mpdtreverse_SOURCES = mpdtreverse.cc mpdtreverse-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstmpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_SOURCES = mpdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 23:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
index 4a6f586..da82359 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index c1e675b..1a2208d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 3d96d9d..c8ea03e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 7f4003b..ab4faee 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index a7d830c..a59b440 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index cc501fe..0d93dde 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 88c4d79..16ee3d5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 37673ca..1674182 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 4d7b090..56a229e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 072580f..a9e475a 100644 (file)
@@ -10,4 +10,4 @@ ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 22:0:0
+libfstngram_la_LDFLAGS = -version-info 23:0:0
index 9113fdf..0a8ef9c 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -355,7 +355,7 @@ lib_LTLIBRARIES = libfstngram.la
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 22:0:0
+libfstngram_la_LDFLAGS = -version-info 23:0:0
 all: all-am
 
 .SUFFIXES:
index 909d6d0..f1a139d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -19,7 +33,7 @@ size_t BitmapIndex::Rank1(size_t end) const {
   DCHECK_LE(end, Bits());
   // TODO(jrosenstock): Remove nullptr support and this special case.
   if (end == 0) return 0;
-  // Without this special case, we'd go past the end.  It's questionable
+  // Without this special case, we'd go past the end. It's questionable
   // whether we should support end == Bits().
   if (end >= num_bits_) return GetOnesCount();
   const uint32 end_word = end / kStorageBitSize;
@@ -173,13 +187,13 @@ std::pair<size_t, size_t> BitmapIndex::Select0s(size_t bit_index) const {
   const int nth = nth_bit(inv_word, remzeros);
 
   // Then, we want to "1-out" everything below that position, and count trailing
-  // ones on the result.  This gives us the position of the next zero.
+  // ones on the result. This gives us the position of the next zero.
   // There is no count trailing ones builtin, so we invert and use count
   // trailing zeros.
 
   // This mask has 1s in the nth+1 low order bits; it is equivalent to
   // (1 << (nth + 1)) - 1, but doesn't need a special case when nth == 63.
-  // We want ~0 in this case anyway.  We want nth+1 because if the bit_index-th
+  // We want ~0 in this case anyway. We want nth+1 because if the bit_index-th
   // zero is in position nth, we need to skip nth+1 positions.
   const uint64 mask = -(uint64{0x2} << nth);  // == ~((2 << nth) - 1)
   const uint64 masked_inv_word = inv_word & mask;
@@ -192,7 +206,7 @@ std::pair<size_t, size_t> BitmapIndex::Select0s(size_t bit_index) const {
             kStorageBitSize * word_index + next_nth};
   } else {
     // TODO(jrosenstock): Try other words in the block.
-    // This should not be massively important.  With a bit density of 1/2,
+    // This should not be massively important. With a bit density of 1/2,
     // 31/32 zeros in a word have the next zero in the same word.
     return {kStorageBitSize * word_index + nth, Select0(bit_index + 1)};
   }
@@ -233,7 +247,7 @@ void BitmapIndex::BuildIndex(const uint64* bits, size_t num_bits,
                              bool enable_select_0_index,
                              bool enable_select_1_index) {
   // Absolute counts are uint32s, so this is the most *set* bits we support
-  // for now.  Just check the number of *input* bits is less than this
+  // for now. Just check the number of *input* bits is less than this
   // to keep things simple.
   DCHECK_LT(num_bits, uint64{1} << 32);
   bits_ = bits;
@@ -297,17 +311,17 @@ void BitmapIndex::BuildIndex(const uint64* bits, size_t num_bits,
 
     if (enable_select_0_index) {
       // Zeros count is somewhat move involved to compute, so only do it
-      // if we need it.  The last word has zeros in the high bits, so
+      // if we need it. The last word has zeros in the high bits, so
       // that needs to be accounted for when computing the zeros count
       // from the ones count.
       const uint32 bits_remaining = num_bits - bit_offset;
       const int word_zeros_count =
           std::min(bits_remaining, kStorageBitSize) - word_ones_count;
 
-      // We record a 0 every kBitsPerSelect0Block bits.  So, if zeros_count
-      // is 0 mod kBitsPerSelect0Block, we record the next zero.  If
+      // We record a 0 every kBitsPerSelect0Block bits. So, if zeros_count
+      // is 0 mod kBitsPerSelect0Block, we record the next zero. If
       // zeros_count is 1 mod kBitsPerSelect0Block, we need to skip
-      // kBitsPerSelect0Block - 1 zeros, then record a zero.  And so on.
+      // kBitsPerSelect0Block - 1 zeros, then record a zero. And so on.
       // What function is this?  It's -zeros_count % kBitsPerSelect0Block.
       const uint32 zeros_to_skip = -zeros_count % kBitsPerSelect0Block;
       if (word_zeros_count > zeros_to_skip) {
@@ -333,8 +347,8 @@ void BitmapIndex::BuildIndex(const uint64* bits, size_t num_bits,
   // We already recorded all the lower relative positions,
   // so we need to do the higher ones.
   // This is only necessary if num_bits % kBitsPerRankIndexEntry != 0,
-  // but if it is 0, we end up in case 7 and do nothing.  This also
-  // holds for num_bits == 0.  If we do have an if statement guarding
+  // but if it is 0, we end up in case 7 and do nothing. This also
+  // holds for num_bits == 0. If we do have an if statement guarding
   // this, mutants complains that it can be changed to if (true).
   // Therefore, we complicate the understanding of the code to please the
   // tools.
@@ -455,7 +469,7 @@ const BitmapIndex::RankIndexEntry& BitmapIndex::FindInvertedRankIndexEntry(
   }
 
   DCHECK_LT(hi, rank_index_.size());
-  // Linear search never showed an advantage when benchmarking.  This may be
+  // Linear search never showed an advantage when benchmarking. This may be
   // because the linear search is more complex with the zeros_count computation,
   // or because the ranges are larger, so linear search is triggered less often,
   // and the difference is harder to measure.
index f21b161..fa9f27c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2b5159f..386891e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -11,7 +25,7 @@ namespace fst {
 #if SIZE_MAX == UINT32_MAX
 
 // 32-bit platforms will be slow when using 64-bit operations; use this
-// table-based version instead.  This only contains constant shifts, which
+// table-based version instead. This only contains constant shifts, which
 // have been benchmarked to be fast.
 
 // These tables were generated using:
index 80f5a7b..497c87d 100644 (file)
@@ -24,7 +24,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstpdtscript.la
 libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-libfstpdtscript_la_LDFLAGS = -version-info 22:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 23:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index c11702f..2542018 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -428,7 +428,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@pdtshortestpath_SOURCES = pdtshortestpath.cc pdtshortestpath-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 23:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
index 2eb6856..f91fa6a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -8,11 +22,11 @@ namespace script {
 
 bool GetPdtComposeFilter(const std::string &str, PdtComposeFilter *cf) {
   if (str == "expand") {
-    *cf = EXPAND_FILTER;
+    *cf = PdtComposeFilter::EXPAND;
   } else if (str == "expand_paren") {
-    *cf = EXPAND_PAREN_FILTER;
+    *cf = PdtComposeFilter::EXPAND_PAREN;
   } else if (str == "paren") {
-    *cf = PAREN_FILTER;
+    *cf = PdtComposeFilter::PAREN;
   } else {
     return false;
   }
@@ -21,9 +35,9 @@ bool GetPdtComposeFilter(const std::string &str, PdtComposeFilter *cf) {
 
 bool GetPdtParserType(const std::string &str, PdtParserType *pt) {
   if (str == "left") {
-    *pt = PDT_LEFT_PARSER;
+    *pt = PdtParserType::LEFT;
   } else if (str == "left_sr") {
-    *pt = PDT_LEFT_SR_PARSER;
+    *pt = PdtParserType::LEFT_SR;
   } else {
     return false;
   }
index b8def6a..cc149c0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 4b5816d..efa3a5c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 36e9f0a..042b02d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 44441d0..6296d72 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 71a6bc0..366623e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 59ef38c..219a2f4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 6a2d087..412685b 100644 (file)
@@ -1,9 +1,24 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 // Converts an RTN represented by FSTs and non-terminal labels into a PDT.
 
 #include <cstring>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -21,19 +36,6 @@ DECLARE_int64(start_paren_labels);
 DECLARE_string(left_paren_prefix);
 DECLARE_string(right_paren_prefix);
 
-namespace fst {
-namespace script {
-namespace {
-
-void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
-  for (const auto &pair : *pairs) delete pair.second;
-  pairs->clear();
-}
-
-}  // namespace
-}  // namespace script
-}  // namespace fst
-
 int pdtreplace_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::PdtParserType;
@@ -53,44 +55,35 @@ int pdtreplace_main(int argc, char **argv) {
     return 1;
   }
 
-  const std::string in_name = argv[1];
   const std::string out_name = argc % 2 == 0 ? argv[argc - 1] : "";
 
-  auto *ifst = FstClass::Read(in_name);
-  if (!ifst) return 1;
-
   PdtParserType parser_type;
   if (!s::GetPdtParserType(FLAGS_pdt_parser_type, &parser_type)) {
     LOG(ERROR) << argv[0]
                << ": Unknown PDT parser type: " << FLAGS_pdt_parser_type;
-    delete ifst;
     return 1;
   }
 
-  std::vector<std::pair<int64, const FstClass *>> pairs;
-  // Note that if the root label is beyond the range of the underlying FST's
-  // labels, truncation will occur.
-  const auto root = atoll(argv[2]);
-  pairs.emplace_back(root, ifst);
-
-  for (auto i = 3; i < argc - 1; i += 2) {
-    ifst = FstClass::Read(argv[i]);
-    if (!ifst) {
-      s::Cleanup(&pairs);
-      return 1;
-    }
+  std::vector<std::pair<int64, std::unique_ptr<const FstClass>>> pairs;
+  for (auto i = 1; i < argc - 1; i += 2) {
+    std::unique_ptr<const FstClass> ifst(FstClass::Read(argv[i]));
+    if (!ifst) return 1;
     // Note that if the root label is beyond the range of the underlying FST's
     // labels, truncation will occur.
     const auto label = atoll(argv[i + 1]);
-    pairs.emplace_back(label, ifst);
+    pairs.emplace_back(label, std::move(ifst));
   }
 
-  VectorFstClass ofst(ifst->ArcType());
+  if (pairs.empty()) {
+    LOG(ERROR) << argv[0] << "At least one replace pair must be provided.";
+    return 1;
+  }
+  const auto root = pairs.front().first;
+  VectorFstClass ofst(pairs.back().second->ArcType());
   std::vector<std::pair<int64, int64>> parens;
-  s::PdtReplace(pairs, &ofst, &parens, root, parser_type,
+  s::PdtReplace(s::BorrowPairs(pairs), &ofst, &parens, root, parser_type,
                 FLAGS_start_paren_labels, FLAGS_left_paren_prefix,
                 FLAGS_right_paren_prefix);
-  s::Cleanup(&pairs);
 
   if (!FLAGS_pdt_parentheses.empty()) {
     if (!WriteLabelPairs(FLAGS_pdt_parentheses, parens)) return 1;
index a2c4a85..8223faa 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 988db91..6961477 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 9ec4fa5..cef93d0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 0a2bf61..bc246a5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index ce0779a..a43a46d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 61ba8ff..aeeb754 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index c4e9b6d..0eadba4 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index 01480d0..2f43cfe 100644 (file)
@@ -1,4 +1,18 @@
 #cython: language_level=3
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
index 02dda61..9b0a120 100644 (file)
@@ -1,4 +1,18 @@
 #cython: language_level=3
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
index 681ebdb..231cff7 100644 (file)
@@ -1,9 +1,24 @@
 #cython: language_level=3
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
 
 from libcpp cimport bool
+from libcpp.memory cimport unique_ptr
 from libcpp.string cimport string
 from libcpp.vector cimport vector
 from libcpp.utility cimport pair
@@ -497,15 +512,19 @@ ctypedef pair[int64, int64] LabelPair
 
 cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
-  enum ArcFilterType:
-    ANY_ARC_FILTER
-    EPSILON_ARC_FILTER
-    INPUT_EPSILON_ARC_FILTER
-    OUTPUT_EPSILON_ARC_FILTER
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum ArcFilterType:
+    ANY_ARC_FILTER "fst::script::ArcFilterType::ANY"
+    EPSILON_ARC_FILTER "fst::script::ArcFilterType::EPSILON"
+    INPUT_EPSILON_ARC_FILTER "fst::script::ArcFilterType::INPUT_EPSILON"
+    OUTPUT_EPSILON_ARC_FILTER "fst::script::ArcFilterType::OUTPUT_EPSILON"
 
-  enum ArcSortType:
-    ILABEL_SORT
-    OLABEL_SORT
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum ArcSortType:
+    ILABEL_SORT "fst::script::ArcSortType::ILABEL"
+    OLABEL_SORT "fst::script::ArcSortType::OLABEL"
 
   cdef void ArcSort(MutableFstClass *, ArcSortType)
 
@@ -513,18 +532,18 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Closure(MutableFstClass *, ClosureType)
 
-  cdef FstClass *CompileFstInternal(istream &,
-                                    const string &,
-                                    const string &,
-                                    const string &,
-                                    const SymbolTable *,
-                                    const SymbolTable *,
-                                    const SymbolTable*,
-                                    bool,
-                                    bool,
-                                    bool,
-                                    bool,
-                                    bool)
+  cdef unique_ptr[FstClass] CompileFstInternal(istream &,
+                                               const string &,
+                                               const string &,
+                                               const string &,
+                                               const SymbolTable *,
+                                               const SymbolTable *,
+                                               const SymbolTable*,
+                                               bool,
+                                               bool,
+                                               bool,
+                                               bool,
+                                               bool)
 
   cdef void Compose(FstClass &, FstClass &, MutableFstClass *,
                     const ComposeOptions &)
@@ -533,7 +552,7 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Connect(MutableFstClass *)
 
-  cdef FstClass *Convert(const FstClass &, const string &)
+  cdef unique_ptr[FstClass] Convert(const FstClass &, const string &)
 
   cdef void Decode(MutableFstClass *, const EncodeMapperClass &)
 
@@ -601,26 +620,28 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef bool Isomorphic(const FstClass &, const FstClass &, float)
 
-  enum MapType:
-    ARC_SUM_MAPPER
-    IDENTITY_MAPPER
-    INPUT_EPSILON_MAPPER
-    INVERT_MAPPER
-    OUTPUT_EPSILON_MAPPER
-    PLUS_MAPPER
-    QUANTIZE_MAPPER
-    RMWEIGHT_MAPPER
-    SUPERFINAL_MAPPER
-    TIMES_MAPPER
-    TO_LOG_MAPPER
-    TO_LOG64_MAPPER
-    TO_STD_MAPPER
-
-  cdef FstClass *Map(const FstClass &,
-                     MapType,
-                     float,
-                     double,
-                     const WeightClass &)
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum MapType:
+    ARC_SUM_MAPPER "fst::script::MapType::ARC_SUM"
+    IDENTITY_MAPPER "fst::script::MapType::IDENTITY"
+    INPUT_EPSILON_MAPPER "fst::script::MapType::INPUT_EPSILON"
+    INVERT_MAPPER "fst::script::MapType::INVERT"
+    OUTPUT_EPSILON_MAPPER "fst::script::MapType::OUTPUT_EPSILON"
+    PLUS_MAPPER "fst::script::MapType::PLUS"
+    QUANTIZE_MAPPER "fst::script::MapType::QUANTIZE"
+    RMWEIGHT_MAPPER "fst::script::MapType::RMWEIGHT"
+    SUPERFINAL_MAPPER "fst::script::MapType::SUPERFINAL"
+    TIMES_MAPPER "fst::script::MapType::TIMES"
+    TO_LOG_MAPPER "fst::script::MapType::TO_LOG"
+    TO_LOG64_MAPPER "fst::script::MapType::TO_LOG64"
+    TO_STD_MAPPER "fst::script::MapType::TO_STD"
+
+  cdef unique_ptr[FstClass] Map(const FstClass &,
+                                MapType,
+                                float,
+                                double,
+                                const WeightClass &)
 
   cdef void Minimize(MutableFstClass *, MutableFstClass *, float, bool)
 
@@ -652,10 +673,12 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Push(MutableFstClass *, ReweightType, float, bool)
 
-  enum RandArcSelection:
-    UNIFORM_ARC_SELECTOR
-    LOG_PROB_ARC_SELECTOR
-    FAST_LOG_PROB_ARC_SELECTOR
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum RandArcSelection:
+    UNIFORM_ARC_SELECTOR "fst::script::RandArcSelection::UNIFORM"
+    LOG_PROB_ARC_SELECTOR "fst::script::RandArcSelection::LOG_PROB"
+    FAST_LOG_PROB_ARC_SELECTOR "fst::script::RandArcSelection::FAST_LOG_PROB"
 
   cdef bool RandEquivalent(const FstClass &,
                            const FstClass &,
@@ -809,7 +832,7 @@ cdef extern from "<fst/extensions/far/far-class.h>" \
 
     # For simplicity, we always use the multiple-file one.
     @staticmethod
-    FarReaderClass *Open(const vector[string] &)
+    unique_ptr[FarReaderClass] Open(const vector[string] &)
 
   cdef cppclass FarWriterClass:
 
@@ -822,4 +845,4 @@ cdef extern from "<fst/extensions/far/far-class.h>" \
     FarType Type()
 
     @staticmethod
-    FarWriterClass *Create(const string &, const string &, FarType)
+    unique_ptr[FarWriterClass] Create(const string &, const string &, FarType)
index 9844e49..1944e01 100644 (file)
@@ -1,4 +1,18 @@
 #cython: language_level=3
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
index 0a73d56..219dbff 100644 (file)
@@ -898,15 +898,15 @@ struct __pyx_obj_9pywrapfst_Fst;
 struct __pyx_obj_9pywrapfst_MutableFst;
 struct __pyx_obj_9pywrapfst_VectorFst;
 struct __pyx_obj_9pywrapfst_Arc;
-struct __pyx_obj_9pywrapfst_ArcIterator;
-struct __pyx_obj_9pywrapfst_MutableArcIterator;
-struct __pyx_obj_9pywrapfst_StateIterator;
+struct __pyx_obj_9pywrapfst__ArcIterator;
+struct __pyx_obj_9pywrapfst__MutableArcIterator;
+struct __pyx_obj_9pywrapfst__StateIterator;
 struct __pyx_obj_9pywrapfst_Compiler;
 struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
 
-/* "cpywrapfst.pxd":507
+/* "cpywrapfst.pxd":509
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
@@ -915,7 +915,7 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
  */
 typedef std::pair<int64,fst::script::FstClass const *>  __pyx_t_10cpywrapfst_LabelFstClassPair;
 
-/* "cpywrapfst.pxd":509
+/* "cpywrapfst.pxd":511
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
@@ -959,7 +959,7 @@ struct __pyx_opt_args_9pywrapfst_reverse;
 struct __pyx_opt_args_9pywrapfst__shortestdistance;
 struct __pyx_opt_args_9pywrapfst_shortestpath;
 
-/* "pywrapfst.pxd":103
+/* "pywrapfst.pxd":104
  * # SymbolTable.
  * 
  * ctypedef fst.SymbolTable * SymbolTable_ptr             # <<<<<<<<<<<<<<
@@ -968,7 +968,7 @@ struct __pyx_opt_args_9pywrapfst_shortestpath;
  */
 typedef fst::SymbolTable *__pyx_t_9pywrapfst_SymbolTable_ptr;
 
-/* "pywrapfst.pxd":104
+/* "pywrapfst.pxd":105
  * 
  * ctypedef fst.SymbolTable * SymbolTable_ptr
  * ctypedef const fst.SymbolTable * const_SymbolTable_ptr             # <<<<<<<<<<<<<<
@@ -977,7 +977,7 @@ typedef fst::SymbolTable *__pyx_t_9pywrapfst_SymbolTable_ptr;
  */
 typedef fst::SymbolTable const *__pyx_t_9pywrapfst_const_SymbolTable_ptr;
 
-/* "pywrapfst.pxd":160
+/* "pywrapfst.pxd":161
  *   cdef fst.SymbolTable *_mutable_raw_ptr_or_raise(self) except *
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=?) except *             # <<<<<<<<<<<<<<
@@ -989,7 +989,7 @@ struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
   int64 key;
 };
 
-/* "pywrapfst.pxd":207
+/* "pywrapfst.pxd":208
  * 
  * 
  * ctypedef fst.EncodeMapperClass * EncodeMapperClass_ptr             # <<<<<<<<<<<<<<
@@ -998,7 +998,7 @@ struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
  */
 typedef fst::script::EncodeMapperClass *__pyx_t_9pywrapfst_EncodeMapperClass_ptr;
 
-/* "pywrapfst.pxd":241
+/* "pywrapfst.pxd":242
  * 
  * 
  * ctypedef fst.FstClass * FstClass_ptr             # <<<<<<<<<<<<<<
@@ -1007,7 +1007,7 @@ typedef fst::script::EncodeMapperClass *__pyx_t_9pywrapfst_EncodeMapperClass_ptr
  */
 typedef fst::script::FstClass *__pyx_t_9pywrapfst_FstClass_ptr;
 
-/* "pywrapfst.pxd":242
+/* "pywrapfst.pxd":243
  * 
  * ctypedef fst.FstClass * FstClass_ptr
  * ctypedef const fst.FstClass * const_FstClass_ptr             # <<<<<<<<<<<<<<
@@ -1016,7 +1016,7 @@ typedef fst::script::FstClass *__pyx_t_9pywrapfst_FstClass_ptr;
  */
 typedef fst::script::FstClass const *__pyx_t_9pywrapfst_const_FstClass_ptr;
 
-/* "pywrapfst.pxd":243
+/* "pywrapfst.pxd":244
  * ctypedef fst.FstClass * FstClass_ptr
  * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr             # <<<<<<<<<<<<<<
@@ -1025,7 +1025,7 @@ typedef fst::script::FstClass const *__pyx_t_9pywrapfst_const_FstClass_ptr;
  */
 typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
 
-/* "pywrapfst.pxd":244
+/* "pywrapfst.pxd":245
  * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr
  * ctypedef fst.VectorFstClass * VectorFstClass_ptr             # <<<<<<<<<<<<<<
@@ -1034,7 +1034,7 @@ typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
  */
 typedef fst::script::VectorFstClass *__pyx_t_9pywrapfst_VectorFstClass_ptr;
 
-/* "pywrapfst.pxd":260
+/* "pywrapfst.pxd":261
  *   cpdef Fst copy(self)
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -1060,7 +1060,7 @@ struct __pyx_opt_args_9pywrapfst_3Fst_draw {
   bool show_weight_one;
 };
 
-/* "pywrapfst.pxd":292
+/* "pywrapfst.pxd":293
  *   cpdef _FstSymbolTableView output_symbols(self)
  * 
  *   cpdef string print(self,             # <<<<<<<<<<<<<<
@@ -1077,7 +1077,7 @@ struct __pyx_opt_args_9pywrapfst_3Fst_print {
   PyObject *missing_sym;
 };
 
-/* "pywrapfst.pxd":325
+/* "pywrapfst.pxd":326
  *   cpdef void add_states(self, size_t)
  * 
  *   cdef void _arcsort(self, sort_type=?) except *             # <<<<<<<<<<<<<<
@@ -1089,7 +1089,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort {
   PyObject *sort_type;
 };
 
-/* "pywrapfst.pxd":327
+/* "pywrapfst.pxd":328
  *   cdef void _arcsort(self, sort_type=?) except *
  * 
  *   cdef void _closure(self, bool closure_plus=?)             # <<<<<<<<<<<<<<
@@ -1101,7 +1101,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__closure {
   bool closure_plus;
 };
 
-/* "pywrapfst.pxd":335
+/* "pywrapfst.pxd":336
  *   cdef void _decode(self, EncodeMapper) except *
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *             # <<<<<<<<<<<<<<
@@ -1113,7 +1113,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs {
   size_t n;
 };
 
-/* "pywrapfst.pxd":337
+/* "pywrapfst.pxd":338
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *
  * 
  *   cdef void _delete_states(self, states=?) except *             # <<<<<<<<<<<<<<
@@ -1125,12 +1125,12 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states {
   PyObject *states;
 };
 
-/* "pywrapfst.pxd":343
+/* "pywrapfst.pxd":344
  *   cdef void _invert(self)
  * 
  *   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cpdef MutableArcIterator mutable_arcs(self, int64 state)
+ *   cpdef _MutableArcIterator mutable_arcs(self, int64 state)
  */
 struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize {
   int __pyx_n;
@@ -1138,7 +1138,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize {
   bool allow_nondet;
 };
 
-/* "pywrapfst.pxd":351
+/* "pywrapfst.pxd":352
  *   cdef void _project(self, project_type) except *
  * 
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *             # <<<<<<<<<<<<<<
@@ -1152,7 +1152,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":353
+/* "pywrapfst.pxd":354
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -1166,7 +1166,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":358
+/* "pywrapfst.pxd":359
  *                   bool to_final=?)
  * 
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *             # <<<<<<<<<<<<<<
@@ -1179,7 +1179,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs {
   PyObject *opairs;
 };
 
-/* "pywrapfst.pxd":360
+/* "pywrapfst.pxd":361
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -1198,7 +1198,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables {
   bool attach_new_osymbols;
 };
 
-/* "pywrapfst.pxd":374
+/* "pywrapfst.pxd":375
  *   cdef void _reserve_states(self, int64 n)
  * 
  *   cdef void _reweight(self, potentials, bool to_final=?) except *             # <<<<<<<<<<<<<<
@@ -1210,7 +1210,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":376
+/* "pywrapfst.pxd":377
  *   cdef void _reweight(self, potentials, bool to_final=?) except *
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -1226,7 +1226,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon {
   float delta;
 };
 
-/* "pywrapfst.pxd":383
+/* "pywrapfst.pxd":384
  *                        float delta=?) except *
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
@@ -1238,7 +1238,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":489
+/* "pywrapfst.pxd":490
  * 
  * 
  * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
@@ -1253,7 +1253,7 @@ struct __pyx_opt_args_9pywrapfst__map {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":491
+/* "pywrapfst.pxd":492
  * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
  * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
@@ -1268,7 +1268,7 @@ struct __pyx_opt_args_9pywrapfst_arcmap {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":493
+/* "pywrapfst.pxd":494
  * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1281,7 +1281,7 @@ struct __pyx_opt_args_9pywrapfst_compose {
   bool connect;
 };
 
-/* "pywrapfst.pxd":498
+/* "pywrapfst.pxd":499
  *                          bool connect=?)
  * 
  * cpdef Fst convert(Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
@@ -1293,7 +1293,7 @@ struct __pyx_opt_args_9pywrapfst_convert {
   PyObject *fst_type;
 };
 
-/* "pywrapfst.pxd":500
+/* "pywrapfst.pxd":501
  * cpdef Fst convert(Fst ifst, fst_type=?)
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1310,7 +1310,7 @@ struct __pyx_opt_args_9pywrapfst_determinize {
   bool increment_subsequential_label;
 };
 
-/* "pywrapfst.pxd":508
+/* "pywrapfst.pxd":509
  *                              bool increment_subsequential_label=?)
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1323,7 +1323,7 @@ struct __pyx_opt_args_9pywrapfst_difference {
   bool connect;
 };
 
-/* "pywrapfst.pxd":513
+/* "pywrapfst.pxd":514
  *                             bool connect=?)
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1338,7 +1338,7 @@ struct __pyx_opt_args_9pywrapfst_disambiguate {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":519
+/* "pywrapfst.pxd":520
  *                               weight=?)
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
@@ -1350,7 +1350,7 @@ struct __pyx_opt_args_9pywrapfst_epsnormalize {
   bool eps_norm_output;
 };
 
-/* "pywrapfst.pxd":521
+/* "pywrapfst.pxd":522
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1362,7 +1362,7 @@ struct __pyx_opt_args_9pywrapfst_equal {
   float delta;
 };
 
-/* "pywrapfst.pxd":523
+/* "pywrapfst.pxd":524
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
@@ -1374,7 +1374,7 @@ struct __pyx_opt_args_9pywrapfst_equivalent {
   float delta;
 };
 
-/* "pywrapfst.pxd":525
+/* "pywrapfst.pxd":526
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1387,7 +1387,7 @@ struct __pyx_opt_args_9pywrapfst_intersect {
   bool connect;
 };
 
-/* "pywrapfst.pxd":530
+/* "pywrapfst.pxd":531
  *                            bool connect=?)
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1399,7 +1399,7 @@ struct __pyx_opt_args_9pywrapfst_isomorphic {
   float delta;
 };
 
-/* "pywrapfst.pxd":532
+/* "pywrapfst.pxd":533
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1413,7 +1413,7 @@ struct __pyx_opt_args_9pywrapfst_prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":537
+/* "pywrapfst.pxd":538
  *                        weight=?)
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1430,7 +1430,7 @@ struct __pyx_opt_args_9pywrapfst_push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":545
+/* "pywrapfst.pxd":546
  *                       bool to_final=?)
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1446,7 +1446,7 @@ struct __pyx_opt_args_9pywrapfst_randequivalent {
   uint64 seed;
 };
 
-/* "pywrapfst.pxd":553
+/* "pywrapfst.pxd":554
  *                           uint64 seed=?) except *
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1463,7 +1463,7 @@ struct __pyx_opt_args_9pywrapfst_randgen {
   uint64 seed;
 };
 
-/* "pywrapfst.pxd":561
+/* "pywrapfst.pxd":562
  *                          uint64 seed=?)
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -1478,7 +1478,7 @@ struct __pyx_opt_args_9pywrapfst_replace {
   int64 return_label;
 };
 
-/* "pywrapfst.pxd":567
+/* "pywrapfst.pxd":568
  *                          int64 return_label=?)
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
@@ -1490,7 +1490,7 @@ struct __pyx_opt_args_9pywrapfst_reverse {
   bool require_superinitial;
 };
 
-/* "pywrapfst.pxd":569
+/* "pywrapfst.pxd":570
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)
  * 
  * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1505,7 +1505,7 @@ struct __pyx_opt_args_9pywrapfst__shortestdistance {
   bool reverse;
 };
 
-/* "pywrapfst.pxd":576
+/* "pywrapfst.pxd":577
  *                             bool reverse=?) except *
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1522,10 +1522,10 @@ struct __pyx_opt_args_9pywrapfst_shortestpath {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":71
+/* "pywrapfst.pxd":72
  * 
  * 
- * cdef class Weight(object):             # <<<<<<<<<<<<<<
+ * cdef class Weight:             # <<<<<<<<<<<<<<
  * 
  *   cdef unique_ptr[fst.WeightClass] _weight
  */
@@ -1536,10 +1536,10 @@ struct __pyx_obj_9pywrapfst_Weight {
 };
 
 
-/* "pywrapfst.pxd":107
+/* "pywrapfst.pxd":108
  * 
  * 
- * cdef class SymbolTableView(object):             # <<<<<<<<<<<<<<
+ * cdef class SymbolTableView:             # <<<<<<<<<<<<<<
  * 
  *   cdef const fst.SymbolTable *_raw(self)
  */
@@ -1549,7 +1549,7 @@ struct __pyx_obj_9pywrapfst_SymbolTableView {
 };
 
 
-/* "pywrapfst.pxd":138
+/* "pywrapfst.pxd":139
  * 
  * 
  * cdef class _EncodeMapperSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1563,7 +1563,7 @@ struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView {
 };
 
 
-/* "pywrapfst.pxd":146
+/* "pywrapfst.pxd":147
  * 
  * 
  * cdef class _FstSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1577,7 +1577,7 @@ struct __pyx_obj_9pywrapfst__FstSymbolTableView {
 };
 
 
-/* "pywrapfst.pxd":154
+/* "pywrapfst.pxd":155
  * 
  * 
  * cdef class _MutableSymbolTable(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1589,7 +1589,7 @@ struct __pyx_obj_9pywrapfst__MutableSymbolTable {
 };
 
 
-/* "pywrapfst.pxd":167
+/* "pywrapfst.pxd":168
  * 
  * 
  * cdef class _MutableFstSymbolTableView(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1603,7 +1603,7 @@ struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView {
 };
 
 
-/* "pywrapfst.pxd":175
+/* "pywrapfst.pxd":176
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1616,10 +1616,10 @@ struct __pyx_obj_9pywrapfst_SymbolTable {
 };
 
 
-/* "pywrapfst.pxd":198
+/* "pywrapfst.pxd":199
  * 
  * 
- * cdef class _SymbolTableIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class _SymbolTableIterator:             # <<<<<<<<<<<<<<
  * 
  *   cdef SymbolTableView _table
  */
@@ -1630,10 +1630,10 @@ struct __pyx_obj_9pywrapfst__SymbolTableIterator {
 };
 
 
-/* "pywrapfst.pxd":210
+/* "pywrapfst.pxd":211
  * 
  * 
- * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
+ * cdef class EncodeMapper:             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.EncodeMapperClass] _mapper
  */
@@ -1644,10 +1644,10 @@ struct __pyx_obj_9pywrapfst_EncodeMapper {
 };
 
 
-/* "pywrapfst.pxd":247
+/* "pywrapfst.pxd":248
  * 
  * 
- * cdef class Fst(object):             # <<<<<<<<<<<<<<
+ * cdef class Fst:             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.FstClass] _fst
  */
@@ -1658,7 +1658,7 @@ struct __pyx_obj_9pywrapfst_Fst {
 };
 
 
-/* "pywrapfst.pxd":313
+/* "pywrapfst.pxd":314
  * 
  * 
  * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
@@ -1671,7 +1671,7 @@ struct __pyx_obj_9pywrapfst_MutableFst {
 };
 
 
-/* "pywrapfst.pxd":394
+/* "pywrapfst.pxd":395
  * 
  * 
  * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
@@ -1683,10 +1683,10 @@ struct __pyx_obj_9pywrapfst_VectorFst {
 };
 
 
-/* "pywrapfst.pxd":416
+/* "pywrapfst.pxd":417
  * 
  * 
- * cdef class Arc(object):             # <<<<<<<<<<<<<<
+ * cdef class Arc:             # <<<<<<<<<<<<<<
  * 
  *   cdef unique_ptr[fst.ArcClass] _arc
  */
@@ -1697,55 +1697,55 @@ struct __pyx_obj_9pywrapfst_Arc {
 };
 
 
-/* "pywrapfst.pxd":426
+/* "pywrapfst.pxd":427
  * 
  * 
- * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class _ArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.FstClass] _fst
  */
-struct __pyx_obj_9pywrapfst_ArcIterator {
+struct __pyx_obj_9pywrapfst__ArcIterator {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtab;
+  struct __pyx_vtabstruct_9pywrapfst__ArcIterator *__pyx_vtab;
   std::shared_ptr<fst::script::FstClass>  _fst;
   std::unique_ptr<fst::script::ArcIteratorClass>  _aiter;
 };
 
 
-/* "pywrapfst.pxd":448
+/* "pywrapfst.pxd":449
  * 
  * 
- * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class _MutableArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.MutableFstClass] _mfst
  */
-struct __pyx_obj_9pywrapfst_MutableArcIterator {
+struct __pyx_obj_9pywrapfst__MutableArcIterator {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtab;
+  struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *__pyx_vtab;
   std::shared_ptr<fst::script::MutableFstClass>  _mfst;
   std::unique_ptr<fst::script::MutableArcIteratorClass>  _aiter;
 };
 
 
-/* "pywrapfst.pxd":472
+/* "pywrapfst.pxd":473
  * 
  * 
- * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class _StateIterator:             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.FstClass] _fst
  */
-struct __pyx_obj_9pywrapfst_StateIterator {
+struct __pyx_obj_9pywrapfst__StateIterator {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtab;
+  struct __pyx_vtabstruct_9pywrapfst__StateIterator *__pyx_vtab;
   std::shared_ptr<fst::script::FstClass>  _fst;
   std::unique_ptr<fst::script::StateIteratorClass>  _siter;
 };
 
 
-/* "pywrapfst.pxd":592
+/* "pywrapfst.pxd":593
  * 
  * 
- * cdef class Compiler(object):             # <<<<<<<<<<<<<<
+ * cdef class Compiler:             # <<<<<<<<<<<<<<
  * 
  *   cdef unique_ptr[stringstream] _sstrm
  */
@@ -1766,10 +1766,10 @@ struct __pyx_obj_9pywrapfst_Compiler {
 };
 
 
-/* "pywrapfst.pxd":613
+/* "pywrapfst.pxd":614
  * # FarReader.
  * 
- * cdef class FarReader(object):             # <<<<<<<<<<<<<<
+ * cdef class FarReader:             # <<<<<<<<<<<<<<
  * 
  *   cdef unique_ptr[fst.FarReaderClass] _reader
  */
@@ -1780,10 +1780,10 @@ struct __pyx_obj_9pywrapfst_FarReader {
 };
 
 
-/* "pywrapfst.pxd":638
+/* "pywrapfst.pxd":639
  * # FarWriter.
  * 
- * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
+ * cdef class FarWriter:             # <<<<<<<<<<<<<<
  * 
  *   cdef unique_ptr[fst.FarWriterClass] _writer
  */
@@ -1794,7 +1794,7 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 };
 
 
-/* "pywrapfst.pyx":3271
+/* "pywrapfst.pyx":3276
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -1803,12 +1803,12 @@ struct __pyx_obj_9pywrapfst_FarWriter {
  */
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ {
   PyObject_HEAD
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self;
+  struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self;
 };
 
 
 
-/* "pywrapfst.pyx":404
+/* "pywrapfst.pyx":406
  * 
  * 
  * cdef class Weight:             # <<<<<<<<<<<<<<
@@ -1826,7 +1826,7 @@ struct __pyx_vtabstruct_9pywrapfst_Weight {
 static struct __pyx_vtabstruct_9pywrapfst_Weight *__pyx_vtabptr_9pywrapfst_Weight;
 
 
-/* "pywrapfst.pyx":731
+/* "pywrapfst.pyx":733
  * 
  * 
  * cdef class SymbolTableView:             # <<<<<<<<<<<<<<
@@ -1853,7 +1853,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTableView {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *__pyx_vtabptr_9pywrapfst_SymbolTableView;
 
 
-/* "pywrapfst.pyx":934
+/* "pywrapfst.pyx":936
  * 
  * 
  * cdef class _EncodeMapperSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1867,7 +1867,7 @@ struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView {
 static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
 
 
-/* "pywrapfst.pyx":958
+/* "pywrapfst.pyx":960
  * 
  * 
  * cdef class _FstSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1881,7 +1881,7 @@ struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView {
 static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
 
 
-/* "pywrapfst.pyx":981
+/* "pywrapfst.pyx":983
  * 
  * 
  * cdef class _MutableSymbolTable(SymbolTableView):             # <<<<<<<<<<<<<<
@@ -1900,7 +1900,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
 
 
-/* "pywrapfst.pyx":1053
+/* "pywrapfst.pyx":1055
  * 
  * 
  * cdef class _MutableFstSymbolTableView(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1914,7 +1914,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
 
 
-/* "pywrapfst.pyx":1068
+/* "pywrapfst.pyx":1070
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1928,7 +1928,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable *__pyx_vtabptr_9pywrapfst_SymbolTable;
 
 
-/* "pywrapfst.pyx":1296
+/* "pywrapfst.pyx":1298
  * 
  * 
  * cdef class EncodeMapper:             # <<<<<<<<<<<<<<
@@ -1950,7 +1950,7 @@ struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
 
 
-/* "pywrapfst.pyx":1563
+/* "pywrapfst.pyx":1565
  * 
  * 
  * cdef class Fst:             # <<<<<<<<<<<<<<
@@ -1961,7 +1961,7 @@ static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst
 struct __pyx_vtabstruct_9pywrapfst_Fst {
   std::string (*_local_render_svg)(std::string const &);
   std::string (*arc_type)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst_ArcIterator *(*arcs)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst__ArcIterator *(*arcs)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst_Fst *(*copy)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   void (*draw)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args);
   struct __pyx_obj_9pywrapfst_Weight *(*final)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
@@ -1973,7 +1973,7 @@ struct __pyx_vtabstruct_9pywrapfst_Fst {
   struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*output_symbols)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   std::string (*print)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args);
   int64 (*start)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst_StateIterator *(*states)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst__StateIterator *(*states)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   bool (*verify)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   std::string (*weight_type)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   void (*write)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch);
@@ -1982,7 +1982,7 @@ struct __pyx_vtabstruct_9pywrapfst_Fst {
 static struct __pyx_vtabstruct_9pywrapfst_Fst *__pyx_vtabptr_9pywrapfst_Fst;
 
 
-/* "pywrapfst.pyx":2028
+/* "pywrapfst.pyx":2030
  * 
  * 
  * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
@@ -2006,7 +2006,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableFst {
   void (*_encode)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *);
   void (*_invert)(struct __pyx_obj_9pywrapfst_MutableFst *);
   void (*_minimize)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args);
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *(*mutable_arcs)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst__MutableArcIterator *(*mutable_arcs)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch);
   int64 (*num_states)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch);
   void (*_project)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *);
   void (*_prune)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args);
@@ -2026,7 +2026,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableFst {
 static struct __pyx_vtabstruct_9pywrapfst_MutableFst *__pyx_vtabptr_9pywrapfst_MutableFst;
 
 
-/* "pywrapfst.pyx":2890
+/* "pywrapfst.pyx":2892
  * 
  * 
  * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
@@ -2040,7 +2040,7 @@ struct __pyx_vtabstruct_9pywrapfst_VectorFst {
 static struct __pyx_vtabstruct_9pywrapfst_VectorFst *__pyx_vtabptr_9pywrapfst_VectorFst;
 
 
-/* "pywrapfst.pyx":3073
+/* "pywrapfst.pyx":3075
  * 
  * 
  * cdef class Arc:             # <<<<<<<<<<<<<<
@@ -2054,67 +2054,67 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":3140
+/* "pywrapfst.pyx":3145
  * 
  * 
- * cdef class ArcIterator:             # <<<<<<<<<<<<<<
+ * cdef class _ArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
-  bool (*done)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  uint8 (*flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  void (*next)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  size_t (*position)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  void (*reset)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  void (*seek)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
-  PyObject *(*value)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst__ArcIterator {
+  bool (*done)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
+  uint8 (*flags)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
+  void (*next)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
+  size_t (*position)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
+  void (*reset)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
+  void (*seek)(struct __pyx_obj_9pywrapfst__ArcIterator *, size_t, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst__ArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
+  PyObject *(*value)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch);
 };
-static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
+static struct __pyx_vtabstruct_9pywrapfst__ArcIterator *__pyx_vtabptr_9pywrapfst__ArcIterator;
 
 
-/* "pywrapfst.pyx":3251
+/* "pywrapfst.pyx":3256
  * 
  * 
- * cdef class MutableArcIterator:             # <<<<<<<<<<<<<<
+ * cdef class _MutableArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
-  bool (*done)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  uint8 (*flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  void (*next)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  size_t (*position)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  void (*reset)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  void (*seek)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
-  void (*set_value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch);
-  PyObject *(*value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator {
+  bool (*done)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
+  uint8 (*flags)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
+  void (*next)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
+  size_t (*position)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
+  void (*reset)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
+  void (*seek)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, size_t, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
+  void (*set_value)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch);
+  PyObject *(*value)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch);
 };
-static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
+static struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *__pyx_vtabptr_9pywrapfst__MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3371
+/* "pywrapfst.pyx":3384
  * 
  * 
- * cdef class StateIterator:             # <<<<<<<<<<<<<<
+ * cdef class _StateIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst_StateIterator {
-  bool (*done)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
-  void (*next)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
-  void (*reset)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
-  int64 (*value)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst__StateIterator {
+  bool (*done)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch);
+  void (*next)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch);
+  void (*reset)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch);
+  int64 (*value)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch);
 };
-static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
+static struct __pyx_vtabstruct_9pywrapfst__StateIterator *__pyx_vtabptr_9pywrapfst__StateIterator;
 
 
-/* "pywrapfst.pyx":4280
+/* "pywrapfst.pyx":4294
  * 
  * 
  * cdef class Compiler:             # <<<<<<<<<<<<<<
@@ -2129,7 +2129,7 @@ struct __pyx_vtabstruct_9pywrapfst_Compiler {
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4417
+/* "pywrapfst.pyx":4431
  * 
  * 
  * cdef class FarReader:             # <<<<<<<<<<<<<<
@@ -2151,7 +2151,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4572
+/* "pywrapfst.pyx":4586
  * 
  * 
  * cdef class FarWriter:             # <<<<<<<<<<<<<<
@@ -2886,7 +2886,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
 static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &__pyx_v_dot); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args); /* proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
@@ -2898,7 +2898,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
 static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_output_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args); /* proto*/
 static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst__StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
@@ -2917,7 +2917,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
 static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args); /* proto*/
-static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
 static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_project_type); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args); /* proto*/
@@ -2934,27 +2934,27 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
 static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
 static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static bool __pyx_f_9pywrapfst_12_ArcIterator_done(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static uint8 __pyx_f_9pywrapfst_12_ArcIterator_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_next(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static size_t __pyx_f_9pywrapfst_12_ArcIterator_position(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_reset(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_seek(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_set_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_12_ArcIterator_value(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static bool __pyx_f_9pywrapfst_19_MutableArcIterator_done(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static uint8 __pyx_f_9pywrapfst_19_MutableArcIterator_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_next(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static size_t __pyx_f_9pywrapfst_19_MutableArcIterator_position(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_reset(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_seek(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_19_MutableArcIterator_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static bool __pyx_f_9pywrapfst_14_StateIterator_done(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_14_StateIterator_next(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_14_StateIterator_reset(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static int64 __pyx_f_9pywrapfst_14_StateIterator_value(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_expression, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
@@ -3016,9 +3016,9 @@ static PyTypeObject *__pyx_ptype_9pywrapfst_Fst = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_MutableFst = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_VectorFst = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_Arc = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst_ArcIterator = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst_MutableArcIterator = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst_StateIterator = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__ArcIterator = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__MutableArcIterator = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__StateIterator = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_Compiler = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_FarReader = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_FarWriter = 0;
@@ -3028,7 +3028,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *); /*proto*/
 static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *); /*proto*/
 static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::string const &); /*proto*/
 static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const &); /*proto*/
-static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &); /*proto*/
+static fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &); /*proto*/
 static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std::string const &, bool); /*proto*/
 static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::string const &, PyObject *); /*proto*/
 static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std::string const &, PyObject *); /*proto*/
@@ -3311,7 +3311,7 @@ static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
 static const char __pyx_k_queue_type[] = "queue_type";
 static const char __pyx_k_subprocess[] = "subprocess";
 static const char __pyx_k_write_text[] = "write_text";
-static const char __pyx_k_ArcIterator[] = "ArcIterator";
+static const char __pyx_k_ArcIterator[] = "_ArcIterator";
 static const char __pyx_k_FstArgError[] = "FstArgError";
 static const char __pyx_k_NO_EPSILONS[] = "NO_EPSILONS";
 static const char __pyx_k_NO_STATE_ID[] = "NO_STATE_ID";
@@ -3355,7 +3355,7 @@ static const char __pyx_k_FstIndexError[] = "FstIndexError";
 static const char __pyx_k_FstProperties[] = "FstProperties";
 static const char __pyx_k_NO_I_EPSILONS[] = "NO_I_EPSILONS";
 static const char __pyx_k_NO_O_EPSILONS[] = "NO_O_EPSILONS";
-static const char __pyx_k_StateIterator[] = "StateIterator";
+static const char __pyx_k_StateIterator[] = "_StateIterator";
 static const char __pyx_k_StopIteration[] = "StopIteration";
 static const char __pyx_k_SymbolTable_2[] = "SymbolTable";
 static const char __pyx_k_available_key[] = "available_key";
@@ -3408,7 +3408,7 @@ static const char __pyx_k_read_from_string[] = "read_from_string";
 static const char __pyx_k_shortestdistance[] = "shortestdistance";
 static const char __pyx_k_ARC_I_LABEL_VALUE[] = "ARC_I_LABEL_VALUE";
 static const char __pyx_k_ARC_O_LABEL_VALUE[] = "ARC_O_LABEL_VALUE";
-static const char __pyx_k_ArcIterator_at_0x[] = "<ArcIterator at 0x";
+static const char __pyx_k_ArcIterator_at_0x[] = "<_ArcIterator at 0x";
 static const char __pyx_k_BINARY_PROPERTIES[] = "BINARY_PROPERTIES";
 static const char __pyx_k_FstBadWeightError[] = "FstBadWeightError";
 static const char __pyx_k_UNWEIGHTED_CYCLES[] = "UNWEIGHTED_CYCLES";
@@ -3418,7 +3418,7 @@ static const char __pyx_k_ADD_ARC_PROPERTIES[] = "ADD_ARC_PROPERTIES";
 static const char __pyx_k_Compilation_failed[] = "Compilation failed";
 static const char __pyx_k_EncodeMapper_at_0x[] = "<EncodeMapper at 0x";
 static const char __pyx_k_FstSymbolTableView[] = "_FstSymbolTableView";
-static const char __pyx_k_MutableArcIterator[] = "MutableArcIterator";
+static const char __pyx_k_MutableArcIterator[] = "_MutableArcIterator";
 static const char __pyx_k_MutableSymbolTable[] = "_MutableSymbolTable";
 static const char __pyx_k_NOT_I_LABEL_SORTED[] = "NOT_I_LABEL_SORTED";
 static const char __pyx_k_NOT_O_LABEL_SORTED[] = "NOT_O_LABEL_SORTED";
@@ -3433,7 +3433,7 @@ static const char __pyx_k_Fst_SymbolTableView[] = "<Fst SymbolTableView ";
 static const char __pyx_k_NON_I_DETERMINISTIC[] = "NON_I_DETERMINISTIC";
 static const char __pyx_k_NON_O_DETERMINISTIC[] = "NON_O_DETERMINISTIC";
 static const char __pyx_k_NotImplementedError[] = "NotImplementedError";
-static const char __pyx_k_StateIterator_at_0x[] = "<StateIterator at 0x";
+static const char __pyx_k_StateIterator_at_0x[] = "<_StateIterator at 0x";
 static const char __pyx_k_SymbolTableIterator[] = "_SymbolTableIterator";
 static const char __pyx_k_attach_new_isymbols[] = "attach_new_isymbols";
 static const char __pyx_k_attach_new_osymbols[] = "attach_new_osymbols";
@@ -3464,12 +3464,12 @@ static const char __pyx_k_Write_to_string_failed[] = "Write to string failed";
 static const char __pyx_k_DELETE_STATE_PROPERTIES[] = "DELETE_STATE_PROPERTIES";
 static const char __pyx_k_Read_from_string_failed[] = "Read from string failed";
 static const char __pyx_k_Unknown_projection_type[] = "Unknown projection type: ";
-static const char __pyx_k_MutableArcIterator_at_0x[] = "<MutableArcIterator at 0x";
+static const char __pyx_k_MutableArcIterator_at_0x[] = "<_MutableArcIterator at 0x";
 static const char __pyx_k_RM_SUPERFINAL_PROPERTIES[] = "RM_SUPERFINAL_PROPERTIES";
 static const char __pyx_k_State_index_out_of_range[] = "State index out of range";
 static const char __pyx_k_ADD_SUPERFINAL_PROPERTIES[] = "ADD_SUPERFINAL_PROPERTIES";
 static const char __pyx_k_Cannot_topsort_cyclic_FST[] = "Cannot topsort cyclic FST";
-static const char __pyx_k_MutableArcIterator___iter[] = "MutableArcIterator.__iter__";
+static const char __pyx_k_MutableArcIterator___iter[] = "_MutableArcIterator.__iter__";
 static const char __pyx_k_MutableFstSymbolTableView[] = "_MutableFstSymbolTableView";
 static const char __pyx_k_SymbolTableIterator_at_0x[] = "<_SymbolTableIterator at 0x";
 static const char __pyx_k_const_Fst_SymbolTableView[] = "<const Fst SymbolTableView ";
@@ -4067,44 +4067,45 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
 static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator___repr__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static int __pyx_pf_9pywrapfst_12_ArcIterator_2__init__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_4__iter__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_6__next__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_8done(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_10flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_12next(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_14position(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_16reset(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_18seek(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_22value(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static int __pyx_pf_9pywrapfst_19_MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_7__next__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_9done(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_11flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_13next(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_15position(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_17reset(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_19seek(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_21set_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_23set_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_25value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_27__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_29__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator___repr__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static int __pyx_pf_9pywrapfst_14_StateIterator_2__init__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_4__iter__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_6__next__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_8done(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_10next(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_12reset(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_14value(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type); /* proto */
@@ -4171,9 +4172,9 @@ static PyObject *__pyx_tp_new_9pywrapfst_Fst(PyTypeObject *t, PyObject *a, PyObj
 static PyObject *__pyx_tp_new_9pywrapfst_MutableFst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_VectorFst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_Arc(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst_ArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst_MutableArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst_StateIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst__ArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst__MutableArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst__StateIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_Compiler(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_FarReader(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_FarWriter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
@@ -4246,7 +4247,7 @@ static PyObject *__pyx_codeobj__68;
 static PyObject *__pyx_codeobj__70;
 /* Late includes */
 
-/* "pywrapfst.pyx":175
+/* "pywrapfst.pyx":177
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4270,7 +4271,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("tostring", 0);
 
-  /* "pywrapfst.pyx":194
+  /* "pywrapfst.pyx":196
  *   """
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):             # <<<<<<<<<<<<<<
@@ -4281,18 +4282,18 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":195
+    /* "pywrapfst.pyx":197
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):
  *     return data             # <<<<<<<<<<<<<<
  *   raise TypeError(f"Expected {str.__name__} but received "
  *                   f"{type(data).__name__}: {data!r}")
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 197, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":194
+    /* "pywrapfst.pyx":196
  *   """
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):             # <<<<<<<<<<<<<<
@@ -4301,14 +4302,14 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":196
+  /* "pywrapfst.pyx":198
  *   if isinstance(data, str):
  *     return data
  *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
  *                   f"{type(data).__name__}: {data!r}")
  * 
  */
-  __pyx_t_4 = PyTuple_New(6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = 0;
   __pyx_t_6 = 127;
@@ -4316,9 +4317,9 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __pyx_t_5 += 9;
   __Pyx_GIVEREF(__pyx_kp_u_Expected);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u_Expected);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6;
@@ -4331,16 +4332,16 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __Pyx_GIVEREF(__pyx_kp_u_but_received);
   PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_but_received);
 
-  /* "pywrapfst.pyx":197
+  /* "pywrapfst.pyx":199
  *     return data
  *   raise TypeError(f"Expected {str.__name__} but received "
  *                   f"{type(data).__name__}: {data!r}")             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 197, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 199, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 197, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 199, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6;
@@ -4352,7 +4353,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __pyx_t_5 += 2;
   __Pyx_GIVEREF(__pyx_kp_u_);
   PyTuple_SET_ITEM(__pyx_t_4, 4, __pyx_kp_u_);
-  __pyx_t_7 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 197, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 199, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6;
   __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7);
@@ -4360,24 +4361,24 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   PyTuple_SET_ITEM(__pyx_t_4, 5, __pyx_t_7);
   __pyx_t_7 = 0;
 
-  /* "pywrapfst.pyx":196
+  /* "pywrapfst.pyx":198
  *   if isinstance(data, str):
  *     return data
  *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
  *                   f"{type(data).__name__}: {data!r}")
  * 
  */
-  __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_4, 6, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_4, 6, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_Raise(__pyx_t_4, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __PYX_ERR(0, 196, __pyx_L1_error)
+  __PYX_ERR(0, 198, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":175
+  /* "pywrapfst.pyx":177
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4397,7 +4398,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":200
+/* "pywrapfst.pyx":202
  * 
  * 
  * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4421,7 +4422,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_tostring", 0);
 
-  /* "pywrapfst.pyx":222
+  /* "pywrapfst.pyx":224
  *   """
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):             # <<<<<<<<<<<<<<
@@ -4432,18 +4433,18 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":223
+    /* "pywrapfst.pyx":225
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):
  *     return data             # <<<<<<<<<<<<<<
  *   elif isinstance(data, numbers.Number):
  *     return str(data)
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 223, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 225, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":222
+    /* "pywrapfst.pyx":224
  *   """
  *   # A Python string can be implicitly cast to a C++ string.
  *   if isinstance(data, str):             # <<<<<<<<<<<<<<
@@ -4452,38 +4453,38 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":224
+  /* "pywrapfst.pyx":226
  *   if isinstance(data, str):
  *     return data
  *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
  *     return str(data)
  *   raise TypeError(f"Expected {str.__name__} but received "
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 224, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 224, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 226, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_2 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 224, __pyx_L1_error)
+  __pyx_t_2 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 226, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":225
+    /* "pywrapfst.pyx":227
  *     return data
  *   elif isinstance(data, numbers.Number):
  *     return str(data)             # <<<<<<<<<<<<<<
  *   raise TypeError(f"Expected {str.__name__} but received "
  *                   f"{type(data).__name__}: {data!r}")
  */
-    __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 225, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 227, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 225, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 227, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":224
+    /* "pywrapfst.pyx":226
  *   if isinstance(data, str):
  *     return data
  *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
@@ -4492,14 +4493,14 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":226
+  /* "pywrapfst.pyx":228
  *   elif isinstance(data, numbers.Number):
  *     return str(data)
  *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
  *                   f"{type(data).__name__}: {data!r}")
  * 
  */
-  __pyx_t_5 = PyTuple_New(6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __pyx_t_6 = 0;
   __pyx_t_7 = 127;
@@ -4507,9 +4508,9 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __pyx_t_6 += 9;
   __Pyx_GIVEREF(__pyx_kp_u_Expected);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Expected);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7;
@@ -4522,16 +4523,16 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __Pyx_GIVEREF(__pyx_kp_u_but_received);
   PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_but_received);
 
-  /* "pywrapfst.pyx":227
+  /* "pywrapfst.pyx":229
  *     return str(data)
  *   raise TypeError(f"Expected {str.__name__} but received "
  *                   f"{type(data).__name__}: {data!r}")             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 227, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 229, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 227, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 229, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
@@ -4543,7 +4544,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __pyx_t_6 += 2;
   __Pyx_GIVEREF(__pyx_kp_u_);
   PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u_);
-  __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 227, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 229, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
   __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -4551,24 +4552,24 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   PyTuple_SET_ITEM(__pyx_t_5, 5, __pyx_t_4);
   __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":226
+  /* "pywrapfst.pyx":228
  *   elif isinstance(data, numbers.Number):
  *     return str(data)
  *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
  *                   f"{type(data).__name__}: {data!r}")
  * 
  */
-  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_5, 6, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_5, 6, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 228, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_Raise(__pyx_t_5, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __PYX_ERR(0, 226, __pyx_L1_error)
+  __PYX_ERR(0, 228, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":200
+  /* "pywrapfst.pyx":202
  * 
  * 
  * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4588,7 +4589,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":230
+/* "pywrapfst.pyx":232
  * 
  * 
  * cdef string path_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4608,16 +4609,16 @@ static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *__pyx_v_data) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("path_tostring", 0);
 
-  /* "pywrapfst.pyx":231
+  /* "pywrapfst.pyx":233
  * 
  * cdef string path_tostring(data) except *:
  *   return tostring(os.fspath(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_os); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_os); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_fspath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 231, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_fspath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -4632,15 +4633,15 @@ static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *__pyx_v_data) {
   }
   __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_data) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_data);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 231, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 231, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_4;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":230
+  /* "pywrapfst.pyx":232
  * 
  * 
  * cdef string path_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4660,7 +4661,7 @@ static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":234
+/* "pywrapfst.pyx":236
  * 
  * 
  * cdef fst.FarType _get_far_type(const string &far_type) except *:             # <<<<<<<<<<<<<<
@@ -4682,7 +4683,7 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_far_type", 0);
 
-  /* "pywrapfst.pyx":250
+  /* "pywrapfst.pyx":252
  *   """
  *   cdef fst.FarType _far_type
  *   if not fst.GetFarType(far_type, addr(_far_type)):             # <<<<<<<<<<<<<<
@@ -4692,21 +4693,21 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
   __pyx_t_1 = ((!(fst::script::GetFarType(__pyx_v_far_type, (&__pyx_v__far_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":251
+    /* "pywrapfst.pyx":253
  *   cdef fst.FarType _far_type
  *   if not fst.GetFarType(far_type, addr(_far_type)):
  *     raise FstArgError(f"Unknown FAR type: {far_type!r}")             # <<<<<<<<<<<<<<
  *   return _far_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_far_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_far_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 251, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_FAR_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_FAR_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4722,14 +4723,14 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 251, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 251, __pyx_L1_error)
+    __PYX_ERR(0, 253, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":250
+    /* "pywrapfst.pyx":252
  *   """
  *   cdef fst.FarType _far_type
  *   if not fst.GetFarType(far_type, addr(_far_type)):             # <<<<<<<<<<<<<<
@@ -4738,7 +4739,7 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
  */
   }
 
-  /* "pywrapfst.pyx":252
+  /* "pywrapfst.pyx":254
  *   if not fst.GetFarType(far_type, addr(_far_type)):
  *     raise FstArgError(f"Unknown FAR type: {far_type!r}")
  *   return _far_type             # <<<<<<<<<<<<<<
@@ -4748,7 +4749,7 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
   __pyx_r = __pyx_v__far_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":234
+  /* "pywrapfst.pyx":236
  * 
  * 
  * cdef fst.FarType _get_far_type(const string &far_type) except *:             # <<<<<<<<<<<<<<
@@ -4769,7 +4770,7 @@ static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":255
+/* "pywrapfst.pyx":257
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4791,7 +4792,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_compose_filter", 0);
 
-  /* "pywrapfst.pyx":277
+  /* "pywrapfst.pyx":279
  *   """
  *   cdef fst.ComposeFilter _compose_filter
  *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):             # <<<<<<<<<<<<<<
@@ -4801,21 +4802,21 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_t_1 = ((!(fst::script::GetComposeFilter(__pyx_v_compose_filter, (&__pyx_v__compose_filter)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":278
+    /* "pywrapfst.pyx":280
  *   cdef fst.ComposeFilter _compose_filter
  *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):
  *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")             # <<<<<<<<<<<<<<
  *   return _compose_filter
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 278, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 280, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 278, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 280, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 278, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 280, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_compose_filter_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 278, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_compose_filter_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 280, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4831,14 +4832,14 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 278, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 280, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 278, __pyx_L1_error)
+    __PYX_ERR(0, 280, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":277
+    /* "pywrapfst.pyx":279
  *   """
  *   cdef fst.ComposeFilter _compose_filter
  *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):             # <<<<<<<<<<<<<<
@@ -4847,7 +4848,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
  */
   }
 
-  /* "pywrapfst.pyx":279
+  /* "pywrapfst.pyx":281
  *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):
  *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")
  *   return _compose_filter             # <<<<<<<<<<<<<<
@@ -4857,7 +4858,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_r = __pyx_v__compose_filter;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":255
+  /* "pywrapfst.pyx":257
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4878,7 +4879,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":282
+/* "pywrapfst.pyx":284
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4900,7 +4901,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_determinize_type", 0);
 
-  /* "pywrapfst.pyx":298
+  /* "pywrapfst.pyx":300
  *   """
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):             # <<<<<<<<<<<<<<
@@ -4910,21 +4911,21 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_t_1 = ((!(fst::script::GetDeterminizeType(__pyx_v_det_type, (&__pyx_v__det_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":299
+    /* "pywrapfst.pyx":301
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):
  *     raise FstArgError(f"Unknown determinization type: {det_type!r}")             # <<<<<<<<<<<<<<
  *   return _det_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 299, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 299, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 299, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 299, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4940,14 +4941,14 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 299, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 299, __pyx_L1_error)
+    __PYX_ERR(0, 301, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":298
+    /* "pywrapfst.pyx":300
  *   """
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):             # <<<<<<<<<<<<<<
@@ -4956,7 +4957,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
  */
   }
 
-  /* "pywrapfst.pyx":300
+  /* "pywrapfst.pyx":302
  *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):
  *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
  *   return _det_type             # <<<<<<<<<<<<<<
@@ -4966,7 +4967,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_r = __pyx_v__det_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":282
+  /* "pywrapfst.pyx":284
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4987,7 +4988,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":303
+/* "pywrapfst.pyx":305
  * 
  * 
  * cdef fst.ProjectType _get_project_type(const string &project_type) except *:             # <<<<<<<<<<<<<<
@@ -5009,7 +5010,7 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_project_type", 0);
 
-  /* "pywrapfst.pyx":319
+  /* "pywrapfst.pyx":321
  *   """
  *   cdef fst.ProjectType _project_type
  *   if not fst.GetProjectType(project_type, addr(_project_type)):             # <<<<<<<<<<<<<<
@@ -5019,21 +5020,21 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
   __pyx_t_1 = ((!(fst::script::GetProjectType(__pyx_v_project_type, (&__pyx_v__project_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":320
+    /* "pywrapfst.pyx":322
  *   cdef fst.ProjectType _project_type
  *   if not fst.GetProjectType(project_type, addr(_project_type)):
  *     raise FstArgError(f"Unknown projection type: {project_type!r}")             # <<<<<<<<<<<<<<
  *   return _project_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 320, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 322, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_project_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 320, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_project_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 322, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 320, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 322, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_projection_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 320, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_projection_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 322, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5049,14 +5050,14 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 320, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 322, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 320, __pyx_L1_error)
+    __PYX_ERR(0, 322, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":319
+    /* "pywrapfst.pyx":321
  *   """
  *   cdef fst.ProjectType _project_type
  *   if not fst.GetProjectType(project_type, addr(_project_type)):             # <<<<<<<<<<<<<<
@@ -5065,7 +5066,7 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
  */
   }
 
-  /* "pywrapfst.pyx":321
+  /* "pywrapfst.pyx":323
  *   if not fst.GetProjectType(project_type, addr(_project_type)):
  *     raise FstArgError(f"Unknown projection type: {project_type!r}")
  *   return _project_type             # <<<<<<<<<<<<<<
@@ -5075,7 +5076,7 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
   __pyx_r = __pyx_v__project_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":303
+  /* "pywrapfst.pyx":305
  * 
  * 
  * cdef fst.ProjectType _get_project_type(const string &project_type) except *:             # <<<<<<<<<<<<<<
@@ -5096,7 +5097,7 @@ static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":324
+/* "pywrapfst.pyx":326
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -5118,7 +5119,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_queue_type", 0);
 
-  /* "pywrapfst.pyx":343
+  /* "pywrapfst.pyx":345
  *   """
  *   cdef fst.QueueType _queue_type
  *   if not fst.GetQueueType(queue_type, addr(_queue_type)):             # <<<<<<<<<<<<<<
@@ -5128,21 +5129,21 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_t_1 = ((!(fst::script::GetQueueType(__pyx_v_queue_type, (&__pyx_v__queue_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":344
+    /* "pywrapfst.pyx":346
  *   cdef fst.QueueType _queue_type
  *   if not fst.GetQueueType(queue_type, addr(_queue_type)):
  *     raise FstArgError(f"Unknown queue type: {queue_type!r}")             # <<<<<<<<<<<<<<
  *   return _queue_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 344, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 346, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 344, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 346, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 344, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 346, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_queue_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 344, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_queue_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 346, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5158,14 +5159,14 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 344, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 346, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 344, __pyx_L1_error)
+    __PYX_ERR(0, 346, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":343
+    /* "pywrapfst.pyx":345
  *   """
  *   cdef fst.QueueType _queue_type
  *   if not fst.GetQueueType(queue_type, addr(_queue_type)):             # <<<<<<<<<<<<<<
@@ -5174,7 +5175,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
  */
   }
 
-  /* "pywrapfst.pyx":345
+  /* "pywrapfst.pyx":347
  *   if not fst.GetQueueType(queue_type, addr(_queue_type)):
  *     raise FstArgError(f"Unknown queue type: {queue_type!r}")
  *   return _queue_type             # <<<<<<<<<<<<<<
@@ -5184,7 +5185,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_r = __pyx_v__queue_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":324
+  /* "pywrapfst.pyx":326
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -5205,7 +5206,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":348
+/* "pywrapfst.pyx":350
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -5213,9 +5214,9 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
  *   """Matches string with the appropriate RandArcSelection enum value.
  */
 
-static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &__pyx_v_select) {
-  enum fst::script::RandArcSelection __pyx_v__select;
-  enum fst::script::RandArcSelection __pyx_r;
+static fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &__pyx_v_select) {
+  fst::script::RandArcSelection __pyx_v__select;
+  fst::script::RandArcSelection __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -5227,7 +5228,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_rand_arc_selection", 0);
 
-  /* "pywrapfst.pyx":368
+  /* "pywrapfst.pyx":370
  *   """
  *   cdef fst.RandArcSelection _select
  *   if not fst.GetRandArcSelection(select, addr(_select)):             # <<<<<<<<<<<<<<
@@ -5237,21 +5238,21 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_t_1 = ((!(fst::script::GetRandArcSelection(__pyx_v_select, (&__pyx_v__select)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":369
+    /* "pywrapfst.pyx":371
  *   cdef fst.RandArcSelection _select
  *   if not fst.GetRandArcSelection(select, addr(_select)):
  *     raise FstArgError(f"Unknown random arc selection type: {select!r}")             # <<<<<<<<<<<<<<
  *   return _select
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_random_arc_selection_typ, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_random_arc_selection_typ, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5267,14 +5268,14 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 369, __pyx_L1_error)
+    __PYX_ERR(0, 371, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":368
+    /* "pywrapfst.pyx":370
  *   """
  *   cdef fst.RandArcSelection _select
  *   if not fst.GetRandArcSelection(select, addr(_select)):             # <<<<<<<<<<<<<<
@@ -5283,7 +5284,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
  */
   }
 
-  /* "pywrapfst.pyx":370
+  /* "pywrapfst.pyx":372
  *   if not fst.GetRandArcSelection(select, addr(_select)):
  *     raise FstArgError(f"Unknown random arc selection type: {select!r}")
  *   return _select             # <<<<<<<<<<<<<<
@@ -5293,7 +5294,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_r = __pyx_v__select;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":348
+  /* "pywrapfst.pyx":350
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -5308,13 +5309,13 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst._get_rand_arc_selection", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = (enum fst::script::RandArcSelection) 0;
+  __pyx_r = (fst::script::RandArcSelection) 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":373
+/* "pywrapfst.pyx":375
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5336,7 +5337,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_replace_label_type", 0);
 
-  /* "pywrapfst.pyx":394
+  /* "pywrapfst.pyx":396
  *   """
  *   cdef fst.ReplaceLabelType _replace_label_type
  *   if not fst.GetReplaceLabelType(replace_label_type,             # <<<<<<<<<<<<<<
@@ -5346,21 +5347,21 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_t_1 = ((!(fst::script::GetReplaceLabelType(__pyx_v_replace_label_type, __pyx_v_epsilon_on_replace, (&__pyx_v__replace_label_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":397
+    /* "pywrapfst.pyx":399
  *                                  epsilon_on_replace,
  *                                  addr(_replace_label_type)):
  *     raise FstArgError(f"Unknown replace label type: {replace_label_type!r}")             # <<<<<<<<<<<<<<
  *   return _replace_label_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 397, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 399, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 397, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 399, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 397, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 399, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_replace_label_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 397, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_replace_label_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 399, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5376,14 +5377,14 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 397, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 399, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 397, __pyx_L1_error)
+    __PYX_ERR(0, 399, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":394
+    /* "pywrapfst.pyx":396
  *   """
  *   cdef fst.ReplaceLabelType _replace_label_type
  *   if not fst.GetReplaceLabelType(replace_label_type,             # <<<<<<<<<<<<<<
@@ -5392,7 +5393,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
  */
   }
 
-  /* "pywrapfst.pyx":398
+  /* "pywrapfst.pyx":400
  *                                  addr(_replace_label_type)):
  *     raise FstArgError(f"Unknown replace label type: {replace_label_type!r}")
  *   return _replace_label_type             # <<<<<<<<<<<<<<
@@ -5402,7 +5403,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_r = __pyx_v__replace_label_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":373
+  /* "pywrapfst.pyx":375
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5423,7 +5424,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":424
+/* "pywrapfst.pyx":426
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5457,7 +5458,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":425
+  /* "pywrapfst.pyx":427
  * 
  *   def __repr__(self):
  *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -5465,7 +5466,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
  *   def __str__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -5475,9 +5476,9 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "type");
-    __PYX_ERR(0, 425, __pyx_L1_error)
+    __PYX_ERR(0, 427, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
   __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -5490,9 +5491,9 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_Weight);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 425, __pyx_L1_error)
+    __PYX_ERR(0, 427, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
   __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -5503,9 +5504,9 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   __pyx_t_2 += 6;
   __Pyx_GIVEREF(__pyx_kp_u_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -5517,14 +5518,14 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":424
+  /* "pywrapfst.pyx":426
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5545,7 +5546,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":427
+/* "pywrapfst.pyx":429
  *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5575,7 +5576,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":428
+  /* "pywrapfst.pyx":430
  * 
  *   def __str__(self):
  *     return self.to_string()             # <<<<<<<<<<<<<<
@@ -5585,15 +5586,15 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 428, __pyx_L1_error)
+    __PYX_ERR(0, 430, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 428, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 430, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":427
+  /* "pywrapfst.pyx":429
  *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5612,7 +5613,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":433
+/* "pywrapfst.pyx":435
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5643,7 +5644,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__float__", 0);
 
-  /* "pywrapfst.pyx":434
+  /* "pywrapfst.pyx":436
  * 
  *   def __float__(self):
  *     return float(self.to_string())             # <<<<<<<<<<<<<<
@@ -5653,18 +5654,18 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 434, __pyx_L1_error)
+    __PYX_ERR(0, 436, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 436, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 434, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 436, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":433
+  /* "pywrapfst.pyx":435
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5684,7 +5685,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":436
+/* "pywrapfst.pyx":438
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5726,11 +5727,11 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 436, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 438, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 436, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 438, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -5743,7 +5744,7 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 436, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 438, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Weight.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -5766,7 +5767,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":437
+  /* "pywrapfst.pyx":439
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5775,20 +5776,20 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 437, __pyx_L1_error)
+    __PYX_ERR(0, 439, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 437, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":438
+  /* "pywrapfst.pyx":440
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weight_tostring(weight)))             # <<<<<<<<<<<<<<
  *     self._check_weight()
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 438, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 440, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":437
+  /* "pywrapfst.pyx":439
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5797,7 +5798,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   __pyx_v_self->_weight.reset(new fst::script::WeightClass(__pyx_t_1, __pyx_t_2));
 
-  /* "pywrapfst.pyx":439
+  /* "pywrapfst.pyx":441
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weight_tostring(weight)))
  *     self._check_weight()             # <<<<<<<<<<<<<<
@@ -5806,11 +5807,11 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 439, __pyx_L1_error)
+    __PYX_ERR(0, 441, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 441, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":436
+  /* "pywrapfst.pyx":438
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5829,7 +5830,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":441
+/* "pywrapfst.pyx":443
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5848,7 +5849,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_check_weight", 0);
 
-  /* "pywrapfst.pyx":442
+  /* "pywrapfst.pyx":444
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5857,19 +5858,19 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "type");
-    __PYX_ERR(0, 442, __pyx_L1_error)
+    __PYX_ERR(0, 444, __pyx_L1_error)
   }
   __pyx_t_1 = ((((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0) == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":443
+    /* "pywrapfst.pyx":445
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *     if not self.member():
  *       raise FstBadWeightError("Invalid weight")
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 443, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 445, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5883,14 +5884,14 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 445, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 443, __pyx_L1_error)
+    __PYX_ERR(0, 445, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":442
+    /* "pywrapfst.pyx":444
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5899,7 +5900,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":444
+  /* "pywrapfst.pyx":446
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5908,19 +5909,19 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 444, __pyx_L1_error)
+    __PYX_ERR(0, 446, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, 0) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":445
+    /* "pywrapfst.pyx":447
  *       raise FstArgError("Weight type not found")
  *     if not self.member():
  *       raise FstBadWeightError("Invalid weight")             # <<<<<<<<<<<<<<
  * 
  *   cpdef Weight copy(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 445, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 447, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5934,14 +5935,14 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Invalid_weight) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Invalid_weight);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 445, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 447, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 445, __pyx_L1_error)
+    __PYX_ERR(0, 447, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":444
+    /* "pywrapfst.pyx":446
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5950,7 +5951,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":441
+  /* "pywrapfst.pyx":443
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5969,7 +5970,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":447
+/* "pywrapfst.pyx":449
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -5999,7 +6000,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_9copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -6016,10 +6017,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 447, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 449, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 447, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 449, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6038,19 +6039,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":453
+  /* "pywrapfst.pyx":455
  *     Returns a copy of the Weight.
  *     """
  *     cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))
  *     return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 453, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 455, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":454
+  /* "pywrapfst.pyx":456
  *     """
  *     cdef Weight _weight = Weight.__new__(Weight)
  *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))             # <<<<<<<<<<<<<<
@@ -6059,15 +6060,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 454, __pyx_L1_error)
+    __PYX_ERR(0, 456, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 454, __pyx_L1_error)
+    __PYX_ERR(0, 456, __pyx_L1_error)
   }
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_weight)));
 
-  /* "pywrapfst.pyx":455
+  /* "pywrapfst.pyx":457
  *     cdef Weight _weight = Weight.__new__(Weight)
  *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))
  *     return _weight             # <<<<<<<<<<<<<<
@@ -6079,7 +6080,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":447
+  /* "pywrapfst.pyx":449
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -6125,7 +6126,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6142,7 +6143,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":461
+/* "pywrapfst.pyx":463
  * 
  *   @classmethod
  *   def zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6173,7 +6174,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10zero(CYTHON_UNUSED PyTypeObject *
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("zero", 0);
 
-  /* "pywrapfst.pyx":467
+  /* "pywrapfst.pyx":469
  *     Constructs semiring zero.
  *     """
  *     return _zero(weight_type)             # <<<<<<<<<<<<<<
@@ -6181,13 +6182,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10zero(CYTHON_UNUSED PyTypeObject *
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 467, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 469, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":461
+  /* "pywrapfst.pyx":463
  * 
  *   @classmethod
  *   def zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6206,7 +6207,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10zero(CYTHON_UNUSED PyTypeObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":470
+/* "pywrapfst.pyx":472
  * 
  *   @classmethod
  *   def one(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6237,7 +6238,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12one(CYTHON_UNUSED PyTypeObject *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("one", 0);
 
-  /* "pywrapfst.pyx":476
+  /* "pywrapfst.pyx":478
  *     Constructs semiring One.
  *     """
  *     return _one(weight_type)             # <<<<<<<<<<<<<<
@@ -6245,13 +6246,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12one(CYTHON_UNUSED PyTypeObject *_
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__one(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 476, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__one(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 478, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":470
+  /* "pywrapfst.pyx":472
  * 
  *   @classmethod
  *   def one(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6270,7 +6271,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12one(CYTHON_UNUSED PyTypeObject *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":479
+/* "pywrapfst.pyx":481
  * 
  *   @classmethod
  *   def no_weight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6301,7 +6302,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14no_weight(CYTHON_UNUSED PyTypeObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("no_weight", 0);
 
-  /* "pywrapfst.pyx":485
+  /* "pywrapfst.pyx":487
  *     Constructs a non-member weight in the semiring.
  *     """
  *     return _no_weight(weight_type)             # <<<<<<<<<<<<<<
@@ -6309,13 +6310,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14no_weight(CYTHON_UNUSED PyTypeObj
  *   def __eq__(Weight w1, Weight w2):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__no_weight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 485, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__no_weight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 487, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":479
+  /* "pywrapfst.pyx":481
  * 
  *   @classmethod
  *   def no_weight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6334,7 +6335,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14no_weight(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":487
+/* "pywrapfst.pyx":489
  *     return _no_weight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6351,7 +6352,7 @@ static PyObject *__pyx_pw_9pywrapfst_6Weight_17__eq__(PyObject *__pyx_v_w1, PyOb
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__eq__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 487, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 489, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6Weight_16__eq__(((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w1), ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w2));
 
   /* function exit code */
@@ -6372,7 +6373,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__eq__", 0);
 
-  /* "pywrapfst.pyx":488
+  /* "pywrapfst.pyx":490
  * 
  *   def __eq__(Weight w1, Weight w2):
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))             # <<<<<<<<<<<<<<
@@ -6382,19 +6383,19 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_w1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 488, __pyx_L1_error)
+    __PYX_ERR(0, 490, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_w2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 488, __pyx_L1_error)
+    __PYX_ERR(0, 490, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyBool_FromLong(operator==((*__pyx_v_w1->_weight), (*__pyx_v_w2->_weight))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 488, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(operator==((*__pyx_v_w1->_weight), (*__pyx_v_w2->_weight))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":487
+  /* "pywrapfst.pyx":489
  *     return _no_weight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6413,7 +6414,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":490
+/* "pywrapfst.pyx":492
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6430,7 +6431,7 @@ static PyObject *__pyx_pw_9pywrapfst_6Weight_19__ne__(PyObject *__pyx_v_w1, PyOb
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__ne__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 490, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 492, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6Weight_18__ne__(((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w1), ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w2));
 
   /* function exit code */
@@ -6452,7 +6453,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__ne__", 0);
 
-  /* "pywrapfst.pyx":491
+  /* "pywrapfst.pyx":493
  * 
  *   def __ne__(Weight w1, Weight w2):
  *     return not w1 == w2             # <<<<<<<<<<<<<<
@@ -6460,16 +6461,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
  *   cpdef string to_string(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_w1), ((PyObject *)__pyx_v_w2), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 491, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 491, __pyx_L1_error)
+  __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_w1), ((PyObject *)__pyx_v_w2), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 493, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 491, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":490
+  /* "pywrapfst.pyx":492
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6488,7 +6489,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":493
+/* "pywrapfst.pyx":495
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6518,7 +6519,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_21to_string)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6534,10 +6535,10 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 493, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 495, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 493, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 495, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6556,7 +6557,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":494
+  /* "pywrapfst.pyx":496
  * 
  *   cpdef string to_string(self):
  *     return self._weight.get().ToString()             # <<<<<<<<<<<<<<
@@ -6565,12 +6566,12 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 494, __pyx_L1_error)
+    __PYX_ERR(0, 496, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->ToString();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":493
+  /* "pywrapfst.pyx":495
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6613,7 +6614,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6630,7 +6631,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":496
+/* "pywrapfst.pyx":498
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6660,7 +6661,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 496, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 498, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_23type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6676,10 +6677,10 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 496, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 498, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 496, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 498, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6698,7 +6699,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     #endif
   }
 
-  /* "pywrapfst.pyx":501
+  /* "pywrapfst.pyx":503
  *     Returns a string indicating the weight type.
  *     """
  *     return self._weight.get().Type()             # <<<<<<<<<<<<<<
@@ -6707,12 +6708,12 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 501, __pyx_L1_error)
+    __PYX_ERR(0, 503, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Type();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":496
+  /* "pywrapfst.pyx":498
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6756,7 +6757,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 496, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 498, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6773,7 +6774,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":503
+/* "pywrapfst.pyx":505
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6803,7 +6804,7 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 503, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 505, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_25member)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6819,10 +6820,10 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 503, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 505, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 503, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 505, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6841,7 +6842,7 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
     #endif
   }
 
-  /* "pywrapfst.pyx":504
+  /* "pywrapfst.pyx":506
  * 
  *   cpdef bool member(self):
  *     return self._weight.get().Member()             # <<<<<<<<<<<<<<
@@ -6850,12 +6851,12 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 504, __pyx_L1_error)
+    __PYX_ERR(0, 506, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Member();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":503
+  /* "pywrapfst.pyx":505
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6898,7 +6899,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_24member(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_6Weight_member(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 503, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_6Weight_member(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 505, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -7028,7 +7029,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_28__setstate_cython__(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":507
+/* "pywrapfst.pyx":509
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7046,19 +7047,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_plus", 0);
 
-  /* "pywrapfst.pyx":508
+  /* "pywrapfst.pyx":510
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                      deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 508, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 510, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":511
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7067,14 +7068,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 511, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 511, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":510
+  /* "pywrapfst.pyx":512
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                      deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7083,10 +7084,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 510, __pyx_L1_error)
+    __PYX_ERR(0, 512, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":511
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7095,7 +7096,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Plus((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":511
+  /* "pywrapfst.pyx":513
  *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                      deref(rhs._weight))))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7107,7 +7108,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":507
+  /* "pywrapfst.pyx":509
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7127,7 +7128,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":514
+/* "pywrapfst.pyx":516
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7171,11 +7172,11 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 514, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 516, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 514, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 516, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7188,14 +7189,14 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 514, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 516, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.plus", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 516, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 516, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_plus(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7217,19 +7218,19 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("plus", 0);
 
-  /* "pywrapfst.pyx":534
+  /* "pywrapfst.pyx":536
  *     FstBadWeightError: invalid weight.
  *   """
  *   cdef Weight _weight = _plus(lhs, rhs)             # <<<<<<<<<<<<<<
  *   _weight._check_weight()
  *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 534, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 536, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":535
+  /* "pywrapfst.pyx":537
  *   """
  *   cdef Weight _weight = _plus(lhs, rhs)
  *   _weight._check_weight()             # <<<<<<<<<<<<<<
@@ -7238,11 +7239,11 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 535, __pyx_L1_error)
+    __PYX_ERR(0, 537, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 535, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 537, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":536
+  /* "pywrapfst.pyx":538
  *   cdef Weight _weight = _plus(lhs, rhs)
  *   _weight._check_weight()
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7254,7 +7255,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":516
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7274,7 +7275,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":539
+/* "pywrapfst.pyx":541
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7292,19 +7293,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_times", 0);
 
-  /* "pywrapfst.pyx":540
+  /* "pywrapfst.pyx":542
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                       deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 540, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":541
+  /* "pywrapfst.pyx":543
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7313,14 +7314,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 541, __pyx_L1_error)
+    __PYX_ERR(0, 543, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 541, __pyx_L1_error)
+    __PYX_ERR(0, 543, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":544
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                       deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7329,10 +7330,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 542, __pyx_L1_error)
+    __PYX_ERR(0, 544, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":541
+  /* "pywrapfst.pyx":543
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7341,7 +7342,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Times((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":543
+  /* "pywrapfst.pyx":545
  *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                       deref(rhs._weight))))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7353,7 +7354,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":539
+  /* "pywrapfst.pyx":541
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7373,7 +7374,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":546
+/* "pywrapfst.pyx":548
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7417,11 +7418,11 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 546, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 548, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 546, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 548, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7434,14 +7435,14 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 546, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 548, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.times", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 546, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 546, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 548, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 548, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_2times(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7463,19 +7464,19 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("times", 0);
 
-  /* "pywrapfst.pyx":566
+  /* "pywrapfst.pyx":568
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight _weight = _times(lhs, rhs)             # <<<<<<<<<<<<<<
  *   _weight._check_weight()
  *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 566, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 568, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":567
+  /* "pywrapfst.pyx":569
  *   """
  *   cdef Weight _weight = _times(lhs, rhs)
  *   _weight._check_weight()             # <<<<<<<<<<<<<<
@@ -7484,11 +7485,11 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 567, __pyx_L1_error)
+    __PYX_ERR(0, 569, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 567, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 569, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":568
+  /* "pywrapfst.pyx":570
  *   cdef Weight _weight = _times(lhs, rhs)
  *   _weight._check_weight()
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7500,7 +7501,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":546
+  /* "pywrapfst.pyx":548
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7520,7 +7521,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":571
+/* "pywrapfst.pyx":573
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7538,19 +7539,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_divide", 0);
 
-  /* "pywrapfst.pyx":572
+  /* "pywrapfst.pyx":574
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                        deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 574, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":573
+  /* "pywrapfst.pyx":575
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7559,14 +7560,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 573, __pyx_L1_error)
+    __PYX_ERR(0, 575, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 573, __pyx_L1_error)
+    __PYX_ERR(0, 575, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":574
+  /* "pywrapfst.pyx":576
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                        deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7575,10 +7576,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 574, __pyx_L1_error)
+    __PYX_ERR(0, 576, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":573
+  /* "pywrapfst.pyx":575
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7587,7 +7588,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Divide((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":575
+  /* "pywrapfst.pyx":577
  *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                        deref(rhs._weight))))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7599,7 +7600,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":571
+  /* "pywrapfst.pyx":573
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7619,7 +7620,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":578
+/* "pywrapfst.pyx":580
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7663,11 +7664,11 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 578, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 580, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 578, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 580, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7680,14 +7681,14 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 578, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 580, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.divide", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 578, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 578, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 580, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 580, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4divide(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7709,19 +7710,19 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("divide", 0);
 
-  /* "pywrapfst.pyx":600
+  /* "pywrapfst.pyx":602
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight _weight = _divide(lhs, rhs)             # <<<<<<<<<<<<<<
  *   _weight._check_weight()
  *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 600, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 602, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":601
+  /* "pywrapfst.pyx":603
  *   """
  *   cdef Weight _weight = _divide(lhs, rhs)
  *   _weight._check_weight()             # <<<<<<<<<<<<<<
@@ -7730,11 +7731,11 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 601, __pyx_L1_error)
+    __PYX_ERR(0, 603, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 601, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 603, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":602
+  /* "pywrapfst.pyx":604
  *   cdef Weight _weight = _divide(lhs, rhs)
  *   _weight._check_weight()
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7746,7 +7747,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":578
+  /* "pywrapfst.pyx":580
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7766,7 +7767,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":605
+/* "pywrapfst.pyx":607
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7784,19 +7785,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_power", 0);
 
-  /* "pywrapfst.pyx":606
+  /* "pywrapfst.pyx":608
  * 
  * cdef Weight _power(Weight w, size_t n):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 606, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 608, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":607
+  /* "pywrapfst.pyx":609
  * cdef Weight _power(Weight w, size_t n):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))             # <<<<<<<<<<<<<<
@@ -7805,15 +7806,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 607, __pyx_L1_error)
+    __PYX_ERR(0, 609, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_w) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 607, __pyx_L1_error)
+    __PYX_ERR(0, 609, __pyx_L1_error)
   }
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Power((*__pyx_v_w->_weight), __pyx_v_n)));
 
-  /* "pywrapfst.pyx":608
+  /* "pywrapfst.pyx":610
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7825,7 +7826,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":605
+  /* "pywrapfst.pyx":607
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7845,7 +7846,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":611
+/* "pywrapfst.pyx":613
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7889,11 +7890,11 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 611, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 613, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 611, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 613, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7902,17 +7903,17 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_w = ((struct __pyx_obj_9pywrapfst_Weight *)values[0]);
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 611, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 613, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 611, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 613, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.power", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 611, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 613, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6power(__pyx_self, __pyx_v_w, __pyx_v_n);
 
   /* function exit code */
@@ -7934,19 +7935,19 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("power", 0);
 
-  /* "pywrapfst.pyx":628
+  /* "pywrapfst.pyx":630
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight _weight = _power(w, n)             # <<<<<<<<<<<<<<
  *   _weight._check_weight()
  *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 630, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":629
+  /* "pywrapfst.pyx":631
  *   """
  *   cdef Weight _weight = _power(w, n)
  *   _weight._check_weight()             # <<<<<<<<<<<<<<
@@ -7955,11 +7956,11 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 629, __pyx_L1_error)
+    __PYX_ERR(0, 631, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 629, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 631, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":630
+  /* "pywrapfst.pyx":632
  *   cdef Weight _weight = _power(w, n)
  *   _weight._check_weight()
  *   return _weight             # <<<<<<<<<<<<<<
@@ -7971,7 +7972,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":611
+  /* "pywrapfst.pyx":613
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7991,7 +7992,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":633
+/* "pywrapfst.pyx":635
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8015,7 +8016,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_zero", 0);
 
-  /* "pywrapfst.pyx":651
+  /* "pywrapfst.pyx":653
  *   """
  *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -8026,7 +8027,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":652
+    /* "pywrapfst.pyx":654
  *   cdef fst.WeightClass _weight
  *   if weight is None:
  *     _weight = fst.WeightClass.Zero(weight_type)             # <<<<<<<<<<<<<<
@@ -8035,7 +8036,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
  */
     __pyx_v__weight = fst::script::WeightClass::Zero(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":651
+    /* "pywrapfst.pyx":653
  *   """
  *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -8045,7 +8046,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":653
+  /* "pywrapfst.pyx":655
  *   if weight is None:
  *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -8056,7 +8057,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":654
+    /* "pywrapfst.pyx":656
  *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
  *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -8065,11 +8066,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 654, __pyx_L1_error)
+      __PYX_ERR(0, 656, __pyx_L1_error)
     }
     __pyx_v__weight = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":653
+    /* "pywrapfst.pyx":655
  *   if weight is None:
  *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -8079,7 +8080,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":656
+  /* "pywrapfst.pyx":658
  *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
@@ -8087,10 +8088,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 656, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 658, __pyx_L1_error)
     __pyx_v__weight = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":657
+    /* "pywrapfst.pyx":659
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():             # <<<<<<<<<<<<<<
@@ -8100,17 +8101,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
     __pyx_t_1 = ((!(__pyx_v__weight.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":658
+      /* "pywrapfst.pyx":660
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
  *   return _weight
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 658, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 660, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 658, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 658, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 660, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 660, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -8125,14 +8126,14 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
       __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 658, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 660, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_4, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __PYX_ERR(0, 658, __pyx_L1_error)
+      __PYX_ERR(0, 660, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":657
+      /* "pywrapfst.pyx":659
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():             # <<<<<<<<<<<<<<
@@ -8143,7 +8144,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":659
+  /* "pywrapfst.pyx":661
  *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -8153,7 +8154,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":633
+  /* "pywrapfst.pyx":635
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8174,7 +8175,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_zero(std:
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":662
+/* "pywrapfst.pyx":664
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_one(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8198,7 +8199,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_one", 0);
 
-  /* "pywrapfst.pyx":680
+  /* "pywrapfst.pyx":682
  *   """
  *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -8209,7 +8210,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":681
+    /* "pywrapfst.pyx":683
  *   cdef fst.WeightClass _weight
  *   if weight is None:
  *     _weight = fst.WeightClass.One(weight_type)             # <<<<<<<<<<<<<<
@@ -8218,7 +8219,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
  */
     __pyx_v__weight = fst::script::WeightClass::One(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":680
+    /* "pywrapfst.pyx":682
  *   """
  *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -8228,7 +8229,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":682
+  /* "pywrapfst.pyx":684
  *   if weight is None:
  *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -8239,7 +8240,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":683
+    /* "pywrapfst.pyx":685
  *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
  *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -8248,11 +8249,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 683, __pyx_L1_error)
+      __PYX_ERR(0, 685, __pyx_L1_error)
     }
     __pyx_v__weight = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":682
+    /* "pywrapfst.pyx":684
  *   if weight is None:
  *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -8262,7 +8263,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":685
+  /* "pywrapfst.pyx":687
  *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
@@ -8270,10 +8271,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 685, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 687, __pyx_L1_error)
     __pyx_v__weight = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":686
+    /* "pywrapfst.pyx":688
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():             # <<<<<<<<<<<<<<
@@ -8283,17 +8284,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
     __pyx_t_1 = ((!(__pyx_v__weight.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":687
+      /* "pywrapfst.pyx":689
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
  *   return _weight
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 687, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 687, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 687, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 689, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -8308,14 +8309,14 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
       __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 687, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_4, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __PYX_ERR(0, 687, __pyx_L1_error)
+      __PYX_ERR(0, 689, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":686
+      /* "pywrapfst.pyx":688
  *   else:
  *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not _weight.Member():             # <<<<<<<<<<<<<<
@@ -8326,7 +8327,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":688
+  /* "pywrapfst.pyx":690
  *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -8336,7 +8337,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":662
+  /* "pywrapfst.pyx":664
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_one(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8357,7 +8358,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_one(std::
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":691
+/* "pywrapfst.pyx":693
  * 
  * 
  * cdef Weight _zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8379,19 +8380,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_zero", 0);
 
-  /* "pywrapfst.pyx":692
+  /* "pywrapfst.pyx":694
  * 
  * cdef Weight _zero(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 692, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 694, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":693
+  /* "pywrapfst.pyx":695
  * cdef Weight _zero(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8400,19 +8401,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 693, __pyx_L1_error)
+    __PYX_ERR(0, 695, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":694
+  /* "pywrapfst.pyx":696
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 694, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 696, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":693
+  /* "pywrapfst.pyx":695
  * cdef Weight _zero(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8421,7 +8422,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::Zero(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":695
+  /* "pywrapfst.pyx":697
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8430,19 +8431,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 695, __pyx_L1_error)
+    __PYX_ERR(0, 697, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v__weight->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":696
+    /* "pywrapfst.pyx":698
  *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 696, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 698, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8456,14 +8457,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
     }
     __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 696, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 698, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 696, __pyx_L1_error)
+    __PYX_ERR(0, 698, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":695
+    /* "pywrapfst.pyx":697
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8472,7 +8473,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
  */
   }
 
-  /* "pywrapfst.pyx":697
+  /* "pywrapfst.pyx":699
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  *   return _weight             # <<<<<<<<<<<<<<
@@ -8484,7 +8485,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":691
+  /* "pywrapfst.pyx":693
  * 
  * 
  * cdef Weight _zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8506,7 +8507,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__zero(PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":700
+/* "pywrapfst.pyx":702
  * 
  * 
  * cdef Weight _one(weight_type):             # <<<<<<<<<<<<<<
@@ -8528,19 +8529,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_one", 0);
 
-  /* "pywrapfst.pyx":701
+  /* "pywrapfst.pyx":703
  * 
  * cdef Weight _one(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 701, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":702
+  /* "pywrapfst.pyx":704
  * cdef Weight _one(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8549,19 +8550,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 702, __pyx_L1_error)
+    __PYX_ERR(0, 704, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":703
+  /* "pywrapfst.pyx":705
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 703, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 705, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":702
+  /* "pywrapfst.pyx":704
  * cdef Weight _one(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8570,7 +8571,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::One(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":704
+  /* "pywrapfst.pyx":706
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8579,19 +8580,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 704, __pyx_L1_error)
+    __PYX_ERR(0, 706, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v__weight->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":705
+    /* "pywrapfst.pyx":707
  *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 705, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 707, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8605,14 +8606,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
     }
     __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 707, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 705, __pyx_L1_error)
+    __PYX_ERR(0, 707, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":704
+    /* "pywrapfst.pyx":706
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
  *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8621,7 +8622,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
  */
   }
 
-  /* "pywrapfst.pyx":706
+  /* "pywrapfst.pyx":708
  *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  *   return _weight             # <<<<<<<<<<<<<<
@@ -8633,7 +8634,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":700
+  /* "pywrapfst.pyx":702
  * 
  * 
  * cdef Weight _one(weight_type):             # <<<<<<<<<<<<<<
@@ -8655,7 +8656,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__one(PyObject *__p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":709
+/* "pywrapfst.pyx":711
  * 
  * 
  * cdef Weight _no_weight(weight_type):             # <<<<<<<<<<<<<<
@@ -8674,19 +8675,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__no_weight(PyObjec
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_no_weight", 0);
 
-  /* "pywrapfst.pyx":710
+  /* "pywrapfst.pyx":712
  * 
  * cdef Weight _no_weight(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":711
+  /* "pywrapfst.pyx":713
  * cdef Weight _no_weight(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8695,19 +8696,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__no_weight(PyObjec
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 711, __pyx_L1_error)
+    __PYX_ERR(0, 713, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":712
+  /* "pywrapfst.pyx":714
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   return _weight
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 712, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 714, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":711
+  /* "pywrapfst.pyx":713
  * cdef Weight _no_weight(weight_type):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(             # <<<<<<<<<<<<<<
@@ -8716,7 +8717,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__no_weight(PyObjec
  */
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::NoWeight(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":713
+  /* "pywrapfst.pyx":715
  *   _weight._weight.reset(
  *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
  *   return _weight             # <<<<<<<<<<<<<<
@@ -8728,7 +8729,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__no_weight(PyObjec
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":709
+  /* "pywrapfst.pyx":711
  * 
  * 
  * cdef Weight _no_weight(weight_type):             # <<<<<<<<<<<<<<
@@ -8748,7 +8749,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__no_weight(PyObjec
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":745
+/* "pywrapfst.pyx":747
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8782,32 +8783,32 @@ static int __pyx_pf_9pywrapfst_15SymbolTableView___init__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":746
+  /* "pywrapfst.pyx":748
  * 
  *   def __init__(self):
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __iter__(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 746, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 746, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 746, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 746, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 746, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 746, __pyx_L1_error)
+  __PYX_ERR(0, 748, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":745
+  /* "pywrapfst.pyx":747
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8825,7 +8826,7 @@ static int __pyx_pf_9pywrapfst_15SymbolTableView___init__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":748
+/* "pywrapfst.pyx":750
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -8855,7 +8856,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":749
+  /* "pywrapfst.pyx":751
  * 
  *   def __iter__(self):
  *     return _SymbolTableIterator(self)             # <<<<<<<<<<<<<<
@@ -8863,13 +8864,13 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(struct __pyx_ob
  *   # Registers the class for pickling.
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst__SymbolTableIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 749, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst__SymbolTableIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 751, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":748
+  /* "pywrapfst.pyx":750
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -8888,7 +8889,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":753
+/* "pywrapfst.pyx":755
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8920,7 +8921,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":754
+  /* "pywrapfst.pyx":756
  * 
  *   def __reduce__(self):
  *     return (_read_SymbolTable_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -8928,20 +8929,20 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_
  *   # Returns a raw const pointer to SymbolTable.
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_SymbolTable_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 754, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_SymbolTable_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 754, __pyx_L1_error)
+    __PYX_ERR(0, 756, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 754, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 754, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 754, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -8953,7 +8954,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":753
+  /* "pywrapfst.pyx":755
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8974,7 +8975,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":760
+/* "pywrapfst.pyx":762
  *   # Should not be directly accessed except by `_raw_ptr_or_raise()`.
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -8987,7 +8988,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":761
+  /* "pywrapfst.pyx":763
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return NULL             # <<<<<<<<<<<<<<
@@ -8997,7 +8998,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":760
+  /* "pywrapfst.pyx":762
  *   # Should not be directly accessed except by `_raw_ptr_or_raise()`.
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -9011,7 +9012,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":764
+/* "pywrapfst.pyx":766
  * 
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
@@ -9029,14 +9030,14 @@ static void __pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent(CYTHON_UNUSE
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raise_nonexistent", 0);
 
-  /* "pywrapfst.pyx":765
+  /* "pywrapfst.pyx":767
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:
  *     raise FstOpError("SymbolTable no longer exists")             # <<<<<<<<<<<<<<
  * 
  *   # Internal API method that should be used when a const pointer to an
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 765, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 767, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_3 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -9050,14 +9051,14 @@ static void __pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent(CYTHON_UNUSE
   }
   __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_SymbolTable_no_longer_exists) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_SymbolTable_no_longer_exists);
   __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 765, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 767, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 765, __pyx_L1_error)
+  __PYX_ERR(0, 767, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":764
+  /* "pywrapfst.pyx":766
  * 
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
@@ -9074,7 +9075,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent(CYTHON_UNUSE
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":769
+/* "pywrapfst.pyx":771
  *   # Internal API method that should be used when a const pointer to an
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -9092,7 +9093,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw_ptr_or_raise", 0);
 
-  /* "pywrapfst.pyx":770
+  /* "pywrapfst.pyx":772
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
  *     cdef const_SymbolTable_ptr _raw = self._raw()             # <<<<<<<<<<<<<<
@@ -9101,11 +9102,11 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw");
-    __PYX_ERR(0, 770, __pyx_L1_error)
+    __PYX_ERR(0, 772, __pyx_L1_error)
   }
   __pyx_v__raw = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw(__pyx_v_self);
 
-  /* "pywrapfst.pyx":771
+  /* "pywrapfst.pyx":773
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
  *     cdef const_SymbolTable_ptr _raw = self._raw()
  *     if _raw == NULL:             # <<<<<<<<<<<<<<
@@ -9115,7 +9116,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   __pyx_t_1 = ((__pyx_v__raw == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":772
+    /* "pywrapfst.pyx":774
  *     cdef const_SymbolTable_ptr _raw = self._raw()
  *     if _raw == NULL:
  *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
@@ -9124,11 +9125,11 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raise_nonexistent");
-      __PYX_ERR(0, 772, __pyx_L1_error)
+      __PYX_ERR(0, 774, __pyx_L1_error)
     }
-    ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raise_nonexistent(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 772, __pyx_L1_error)
+    ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raise_nonexistent(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 774, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":771
+    /* "pywrapfst.pyx":773
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
  *     cdef const_SymbolTable_ptr _raw = self._raw()
  *     if _raw == NULL:             # <<<<<<<<<<<<<<
@@ -9137,7 +9138,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
  */
   }
 
-  /* "pywrapfst.pyx":773
+  /* "pywrapfst.pyx":775
  *     if _raw == NULL:
  *       self._raise_nonexistent()
  *     return _raw             # <<<<<<<<<<<<<<
@@ -9147,7 +9148,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   __pyx_r = __pyx_v__raw;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":769
+  /* "pywrapfst.pyx":771
  *   # Internal API method that should be used when a const pointer to an
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -9164,7 +9165,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":775
+/* "pywrapfst.pyx":777
  *     return _raw
  * 
  *   cpdef int64 available_key(self) except *:             # <<<<<<<<<<<<<<
@@ -9195,7 +9196,7 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 775, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 777, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_7available_key)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -9211,10 +9212,10 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 777, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 775, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 777, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9233,7 +9234,7 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj
     #endif
   }
 
-  /* "pywrapfst.pyx":781
+  /* "pywrapfst.pyx":783
  *     Returns an integer indicating the next available key index in the table.
  *     """
  *     return self._raw_ptr_or_raise().AvailableKey()             # <<<<<<<<<<<<<<
@@ -9242,13 +9243,13 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 781, __pyx_L1_error)
+    __PYX_ERR(0, 783, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 781, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 783, __pyx_L1_error)
   __pyx_r = __pyx_t_6->AvailableKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":775
+  /* "pywrapfst.pyx":777
  *     return _raw
  * 
  *   cpdef int64 available_key(self) except *:             # <<<<<<<<<<<<<<
@@ -9293,8 +9294,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_6available_key(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("available_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_available_key(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 775, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_available_key(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 777, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 777, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9311,7 +9312,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_6available_key(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":783
+/* "pywrapfst.pyx":785
  *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
@@ -9341,7 +9342,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 785, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_9checksum)) {
         __Pyx_XDECREF(__pyx_r);
@@ -9358,10 +9359,10 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 785, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 783, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 785, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9380,7 +9381,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":789
+  /* "pywrapfst.pyx":791
  *     Returns a bytestring indicating the label-independent MD5 checksum.
  *     """
  *     return self._raw_ptr_or_raise().CheckSum()             # <<<<<<<<<<<<<<
@@ -9390,16 +9391,16 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 789, __pyx_L1_error)
+    __PYX_ERR(0, 791, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 789, __pyx_L1_error)
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->CheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 789, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 791, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->CheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 791, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":783
+  /* "pywrapfst.pyx":785
  *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
@@ -9444,7 +9445,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_8checksum(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 785, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9461,7 +9462,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_8checksum(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":791
+/* "pywrapfst.pyx":793
  *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9491,7 +9492,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTable
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 791, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 793, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_11copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -9508,10 +9509,10 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTable
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 791, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 793, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 791, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 793, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9530,7 +9531,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTable
     #endif
   }
 
-  /* "pywrapfst.pyx":797
+  /* "pywrapfst.pyx":799
  *     Returns a mutable copy of the SymbolTable.
  *     """
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))             # <<<<<<<<<<<<<<
@@ -9540,16 +9541,16 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTable
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 797, __pyx_L1_error)
+    __PYX_ERR(0, 799, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 797, __pyx_L1_error)
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(__pyx_t_5->Copy()))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 797, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 799, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(__pyx_t_5->Copy()))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 799, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":791
+  /* "pywrapfst.pyx":793
  *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9594,7 +9595,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_10copy(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_15SymbolTableView_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 791, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_15SymbolTableView_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 793, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9611,7 +9612,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_10copy(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":799
+/* "pywrapfst.pyx":801
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9653,7 +9654,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find", 0);
 
-  /* "pywrapfst.pyx":816
+  /* "pywrapfst.pyx":818
  *           not found.
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -9662,12 +9663,12 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 816, __pyx_L1_error)
+    __PYX_ERR(0, 818, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 816, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 818, __pyx_L1_error)
   __pyx_v__raw = __pyx_t_1;
 
-  /* "pywrapfst.pyx":817
+  /* "pywrapfst.pyx":819
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -9683,7 +9684,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
     __Pyx_XGOTREF(__pyx_t_4);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":818
+      /* "pywrapfst.pyx":820
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:
  *       return _raw.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
@@ -9691,14 +9692,14 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
  *       return _raw.FindSymbol(key)
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 818, __pyx_L3_error)
-      __pyx_t_6 = __Pyx_PyInt_From_int64_t(__pyx_v__raw->Find(__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 818, __pyx_L3_error)
+      __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 820, __pyx_L3_error)
+      __pyx_t_6 = __Pyx_PyInt_From_int64_t(__pyx_v__raw->Find(__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 820, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_r = __pyx_t_6;
       __pyx_t_6 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":817
+      /* "pywrapfst.pyx":819
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -9709,7 +9710,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":819
+    /* "pywrapfst.pyx":821
  *     try:
  *       return _raw.FindIndex(tostring(key))
  *     except TypeError:             # <<<<<<<<<<<<<<
@@ -9719,12 +9720,12 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
     __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError);
     if (__pyx_t_7) {
       __Pyx_AddTraceback("pywrapfst.SymbolTableView.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 819, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 821, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GOTREF(__pyx_t_9);
 
-      /* "pywrapfst.pyx":820
+      /* "pywrapfst.pyx":822
  *       return _raw.FindIndex(tostring(key))
  *     except TypeError:
  *       return _raw.FindSymbol(key)             # <<<<<<<<<<<<<<
@@ -9732,8 +9733,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 820, __pyx_L5_except_error)
-      __pyx_t_11 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__raw->Find(__pyx_t_10)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 820, __pyx_L5_except_error)
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L5_except_error)
+      __pyx_t_11 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__raw->Find(__pyx_t_10)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 822, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_11);
       __pyx_r = __pyx_t_11;
       __pyx_t_11 = 0;
@@ -9745,7 +9746,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":817
+    /* "pywrapfst.pyx":819
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -9771,7 +9772,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":799
+  /* "pywrapfst.pyx":801
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9793,7 +9794,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":822
+/* "pywrapfst.pyx":824
  *       return _raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
@@ -9825,10 +9826,10 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 822, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 824, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key)) {
-        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 822, __pyx_L1_error)
+        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 824, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -9844,10 +9845,10 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 822, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 824, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 824, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9866,7 +9867,7 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":834
+  /* "pywrapfst.pyx":836
  *       The integer index of the n-th key, or NO_LABEL if not found.
  *     """
  *     return self._raw_ptr_or_raise().GetNthKey(pos)             # <<<<<<<<<<<<<<
@@ -9875,13 +9876,13 @@ static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 834, __pyx_L1_error)
+    __PYX_ERR(0, 836, __pyx_L1_error)
   }
-  __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 834, __pyx_L1_error)
+  __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 836, __pyx_L1_error)
   __pyx_r = __pyx_t_7->GetNthKey(__pyx_v_pos);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":822
+  /* "pywrapfst.pyx":824
  *       return _raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
@@ -9915,7 +9916,7 @@ static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key(PyObject *_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_nth_key (wrapper)", 0);
   assert(__pyx_arg_pos); {
-    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L3_error)
+    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 824, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -9940,8 +9941,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_14get_nth_key(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_nth_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 822, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 824, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 824, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9958,7 +9959,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_14get_nth_key(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":836
+/* "pywrapfst.pyx":838
  *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
@@ -9988,7 +9989,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 836, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 838, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum)) {
         __Pyx_XDECREF(__pyx_r);
@@ -10005,10 +10006,10 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 836, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 838, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 836, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 838, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10027,7 +10028,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __
     #endif
   }
 
-  /* "pywrapfst.pyx":842
+  /* "pywrapfst.pyx":844
  *     Returns a bytestring indicating the label-dependent MD5 checksum.
  *     """
  *     return self._raw_ptr_or_raise().LabeledCheckSum()             # <<<<<<<<<<<<<<
@@ -10037,16 +10038,16 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 842, __pyx_L1_error)
+    __PYX_ERR(0, 844, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 842, __pyx_L1_error)
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->LabeledCheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 842, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 844, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->LabeledCheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 844, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":836
+  /* "pywrapfst.pyx":838
  *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
@@ -10091,7 +10092,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_16labeled_checksum(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("labeled_checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 836, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 838, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10108,7 +10109,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_16labeled_checksum(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":844
+/* "pywrapfst.pyx":846
  *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
  *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
@@ -10146,7 +10147,7 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 844, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 846, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_19member)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10162,10 +10163,10 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_key) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 844, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 846, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 844, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 846, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10184,7 +10185,7 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":860
+  /* "pywrapfst.pyx":862
  *       Whether or not the key is present (as a string or a index) in the table.
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -10193,12 +10194,12 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 860, __pyx_L1_error)
+    __PYX_ERR(0, 862, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 860, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 862, __pyx_L1_error)
   __pyx_v__raw = __pyx_t_6;
 
-  /* "pywrapfst.pyx":861
+  /* "pywrapfst.pyx":863
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -10214,18 +10215,18 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     __Pyx_XGOTREF(__pyx_t_9);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":862
+      /* "pywrapfst.pyx":864
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:
  *       return _raw.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
  *     except TypeError:
  *       return _raw.MemberIndex(key)
  */
-      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 862, __pyx_L3_error)
+      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 864, __pyx_L3_error)
       __pyx_r = __pyx_v__raw->Member(__pyx_t_10);
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":861
+      /* "pywrapfst.pyx":863
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -10239,7 +10240,7 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":863
+    /* "pywrapfst.pyx":865
  *     try:
  *       return _raw.MemberSymbol(tostring(key))
  *     except TypeError:             # <<<<<<<<<<<<<<
@@ -10249,19 +10250,19 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError);
     if (__pyx_t_11) {
       __Pyx_AddTraceback("pywrapfst.SymbolTableView.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 863, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 865, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_GOTREF(__pyx_t_3);
 
-      /* "pywrapfst.pyx":864
+      /* "pywrapfst.pyx":866
  *       return _raw.MemberSymbol(tostring(key))
  *     except TypeError:
  *       return _raw.MemberIndex(key)             # <<<<<<<<<<<<<<
  * 
  *   cpdef string name(self) except *:
  */
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 864, __pyx_L5_except_error)
+      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 866, __pyx_L5_except_error)
       __pyx_r = __pyx_v__raw->Member(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -10271,7 +10272,7 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":861
+    /* "pywrapfst.pyx":863
  *     """
  *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
@@ -10297,7 +10298,7 @@ static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrap
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":844
+  /* "pywrapfst.pyx":846
  *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
  *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
@@ -10342,8 +10343,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_18member(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_member(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 844, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 844, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_member(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 846, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 846, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -10360,7 +10361,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_18member(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":866
+/* "pywrapfst.pyx":868
  *       return _raw.MemberIndex(key)
  * 
  *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
@@ -10391,7 +10392,7 @@ static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9p
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 866, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 868, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_21name)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10407,10 +10408,10 @@ static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9p
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 868, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 866, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 868, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10429,7 +10430,7 @@ static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9p
     #endif
   }
 
-  /* "pywrapfst.pyx":872
+  /* "pywrapfst.pyx":874
  *     Returns the symbol table's name.
  *     """
  *     return self._raw_ptr_or_raise().Name()             # <<<<<<<<<<<<<<
@@ -10438,13 +10439,13 @@ static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 872, __pyx_L1_error)
+    __PYX_ERR(0, 874, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 872, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 874, __pyx_L1_error)
   __pyx_r = __pyx_t_6->Name();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":866
+  /* "pywrapfst.pyx":868
  *       return _raw.MemberIndex(key)
  * 
  *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
@@ -10489,8 +10490,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_20name(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_name(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 866, __pyx_L1_error)
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_name(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 868, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 868, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -10507,7 +10508,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_20name(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":874
+/* "pywrapfst.pyx":876
  *     return self._raw_ptr_or_raise().Name()
  * 
  *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
@@ -10538,7 +10539,7 @@ static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 874, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 876, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10554,10 +10555,10 @@ static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 874, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 876, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 874, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 876, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10576,7 +10577,7 @@ static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":880
+  /* "pywrapfst.pyx":882
  *     Returns the number of symbols in the symbol table.
  *     """
  *     return self._raw_ptr_or_raise().NumSymbols()             # <<<<<<<<<<<<<<
@@ -10585,13 +10586,13 @@ static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 880, __pyx_L1_error)
+    __PYX_ERR(0, 882, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 880, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 882, __pyx_L1_error)
   __pyx_r = __pyx_t_6->NumSymbols();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":874
+  /* "pywrapfst.pyx":876
  *     return self._raw_ptr_or_raise().Name()
  * 
  *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
@@ -10636,8 +10637,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_22num_symbols(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 874, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 874, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 876, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 876, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -10654,7 +10655,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_22num_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":882
+/* "pywrapfst.pyx":884
  *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10685,7 +10686,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 882, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 884, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_25write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10701,7 +10702,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 882, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 884, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -10721,7 +10722,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":896
+  /* "pywrapfst.pyx":898
  *       FstIOError: Write failed.
  *     """
  *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -10730,25 +10731,25 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 896, __pyx_L1_error)
+    __PYX_ERR(0, 898, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 896, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 896, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 898, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 898, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_t_5->Write(__pyx_t_6) != 0)) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":897
+    /* "pywrapfst.pyx":899
  *     """
  *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):
  *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write_text(self, source) except *:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 897, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 897, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 899, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 897, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 899, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -10764,14 +10765,14 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 897, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 899, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 897, __pyx_L1_error)
+    __PYX_ERR(0, 899, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":896
+    /* "pywrapfst.pyx":898
  *       FstIOError: Write failed.
  *     """
  *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -10780,7 +10781,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":882
+  /* "pywrapfst.pyx":884
  *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10823,8 +10824,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_24write(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_15SymbolTableView_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 882, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 882, __pyx_L1_error)
+  __pyx_f_9pywrapfst_15SymbolTableView_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 884, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 884, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10841,7 +10842,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_24write(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":899
+/* "pywrapfst.pyx":901
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10872,7 +10873,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 899, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 901, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_27write_text)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10888,7 +10889,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 899, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -10908,7 +10909,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
     #endif
   }
 
-  /* "pywrapfst.pyx":913
+  /* "pywrapfst.pyx":915
  *       FstIOError: Write failed.
  *     """
  *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -10917,25 +10918,25 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 913, __pyx_L1_error)
+    __PYX_ERR(0, 915, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 913, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 913, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 915, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 915, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_t_5->WriteText(__pyx_t_6) != 0)) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":914
+    /* "pywrapfst.pyx":916
  *     """
  *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):
  *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 914, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 916, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 916, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 914, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 916, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -10951,14 +10952,14 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 914, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 914, __pyx_L1_error)
+    __PYX_ERR(0, 916, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":913
+    /* "pywrapfst.pyx":915
  *       FstIOError: Write failed.
  *     """
  *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -10967,7 +10968,7 @@ static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":899
+  /* "pywrapfst.pyx":901
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
@@ -11010,8 +11011,8 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_26write_text(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_text", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_15SymbolTableView_write_text(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 899, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 899, __pyx_L1_error)
+  __pyx_f_9pywrapfst_15SymbolTableView_write_text(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 901, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 901, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11028,7 +11029,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_26write_text(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":916
+/* "pywrapfst.pyx":918
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -11060,7 +11061,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
@@ -11077,10 +11078,10 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 916, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 918, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 916, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 918, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -11099,7 +11100,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
     #endif
   }
 
-  /* "pywrapfst.pyx":929
+  /* "pywrapfst.pyx":931
  *     """
  *     cdef stringstream _sstrm
  *     if not self._raw_ptr_or_raise().Write(_sstrm):             # <<<<<<<<<<<<<<
@@ -11108,20 +11109,20 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 929, __pyx_L1_error)
+    __PYX_ERR(0, 931, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 929, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 931, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_t_5->Write(__pyx_v__sstrm) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":930
+    /* "pywrapfst.pyx":932
  *     cdef stringstream _sstrm
  *     if not self._raw_ptr_or_raise().Write(_sstrm):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 930, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 932, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -11135,14 +11136,14 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 930, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 932, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 930, __pyx_L1_error)
+    __PYX_ERR(0, 932, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":929
+    /* "pywrapfst.pyx":931
  *     """
  *     cdef stringstream _sstrm
  *     if not self._raw_ptr_or_raise().Write(_sstrm):             # <<<<<<<<<<<<<<
@@ -11151,7 +11152,7 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
  */
   }
 
-  /* "pywrapfst.pyx":931
+  /* "pywrapfst.pyx":933
  *     if not self._raw_ptr_or_raise().Write(_sstrm):
  *       raise FstIOError("Write to string failed")
  *     return _sstrm.str()             # <<<<<<<<<<<<<<
@@ -11159,13 +11160,13 @@ static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __p
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 931, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 933, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":916
+  /* "pywrapfst.pyx":918
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -11210,7 +11211,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_28write_to_string(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11227,7 +11228,7 @@ static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_28write_to_string(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":949
+/* "pywrapfst.pyx":951
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11262,7 +11263,7 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":950
+  /* "pywrapfst.pyx":952
  * 
  *   def __repr__(self):
  *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
@@ -11270,7 +11271,7 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 952, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -11280,12 +11281,12 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_const_EncodeMapper_SymbolTableV);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 950, __pyx_L1_error)
+    __PYX_ERR(0, 952, __pyx_L1_error)
   }
-  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 950, __pyx_L1_error)
-  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 952, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 952, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 952, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
@@ -11298,16 +11299,16 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   __Pyx_GIVEREF(__pyx_kp_u_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
 
-  /* "pywrapfst.pyx":951
+  /* "pywrapfst.pyx":953
  *   def __repr__(self):
  *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "
  *             f"at 0x{id(self):x}>")             # <<<<<<<<<<<<<<
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  */
-  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 951, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 953, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 951, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 953, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -11320,21 +11321,21 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
 
-  /* "pywrapfst.pyx":950
+  /* "pywrapfst.pyx":952
  * 
  *   def __repr__(self):
  *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
  *             f"at 0x{id(self):x}>")
  * 
  */
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 952, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":949
+  /* "pywrapfst.pyx":951
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11355,7 +11356,7 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":953
+/* "pywrapfst.pyx":955
  *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11372,7 +11373,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":954
+  /* "pywrapfst.pyx":956
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._mapper.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
@@ -11381,17 +11382,17 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 954, __pyx_L1_error)
+    __PYX_ERR(0, 956, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 954, __pyx_L1_error)
+      __PYX_ERR(0, 956, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mapper.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":955
+    /* "pywrapfst.pyx":957
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._mapper.get().InputSymbols() if self._input_side
  *             else self._mapper.get().OutputSymbols())             # <<<<<<<<<<<<<<
@@ -11400,14 +11401,14 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 955, __pyx_L1_error)
+      __PYX_ERR(0, 957, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mapper.get()->OutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":953
+  /* "pywrapfst.pyx":955
  *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11424,7 +11425,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":972
+/* "pywrapfst.pyx":974
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11459,7 +11460,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":973
+  /* "pywrapfst.pyx":975
  * 
  *   def __repr__(self):
  *     return (f"<const Fst SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
@@ -11467,7 +11468,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 973, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -11477,12 +11478,12 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_const_Fst_SymbolTableView);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 973, __pyx_L1_error)
+    __PYX_ERR(0, 975, __pyx_L1_error)
   }
-  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 973, __pyx_L1_error)
-  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 973, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 975, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 973, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
@@ -11495,16 +11496,16 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   __Pyx_GIVEREF(__pyx_kp_u_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
 
-  /* "pywrapfst.pyx":974
+  /* "pywrapfst.pyx":976
  *   def __repr__(self):
  *     return (f"<const Fst SymbolTableView {self.name()!r} "
  *             f"at 0x{id(self):x}>")             # <<<<<<<<<<<<<<
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  */
-  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 974, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 976, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 974, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 976, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -11517,21 +11518,21 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
 
-  /* "pywrapfst.pyx":973
+  /* "pywrapfst.pyx":975
  * 
  *   def __repr__(self):
  *     return (f"<const Fst SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
  *             f"at 0x{id(self):x}>")
  * 
  */
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 973, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":972
+  /* "pywrapfst.pyx":974
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11552,7 +11553,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":976
+/* "pywrapfst.pyx":978
  *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11569,7 +11570,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":977
+  /* "pywrapfst.pyx":979
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._fst.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
@@ -11578,17 +11579,17 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 977, __pyx_L1_error)
+    __PYX_ERR(0, 979, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 977, __pyx_L1_error)
+      __PYX_ERR(0, 979, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":978
+    /* "pywrapfst.pyx":980
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._fst.get().InputSymbols() if self._input_side
  *             else self._fst.get().OutputSymbols())             # <<<<<<<<<<<<<<
@@ -11597,14 +11598,14 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 978, __pyx_L1_error)
+      __PYX_ERR(0, 980, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_fst.get()->OutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":976
+  /* "pywrapfst.pyx":978
  *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11621,7 +11622,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":992
+/* "pywrapfst.pyx":994
  *   """
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11637,7 +11638,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSym
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":993
+  /* "pywrapfst.pyx":995
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return self._mutable_raw()             # <<<<<<<<<<<<<<
@@ -11646,12 +11647,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSym
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw");
-    __PYX_ERR(0, 993, __pyx_L1_error)
+    __PYX_ERR(0, 995, __pyx_L1_error)
   }
   __pyx_r = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":992
+  /* "pywrapfst.pyx":994
  *   """
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11668,7 +11669,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSym
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":999
+/* "pywrapfst.pyx":1001
  *   # Should not be directly accessed except by `_mutable__raw_ptr_or_raise()`.
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -11681,7 +11682,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":1000
+  /* "pywrapfst.pyx":1002
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return NULL             # <<<<<<<<<<<<<<
@@ -11691,7 +11692,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":999
+  /* "pywrapfst.pyx":1001
  *   # Should not be directly accessed except by `_mutable__raw_ptr_or_raise()`.
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -11705,7 +11706,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1004
+/* "pywrapfst.pyx":1006
  *   # Internal API method that should be used when a mutable pointer to an
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -11723,7 +11724,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw_ptr_or_raise", 0);
 
-  /* "pywrapfst.pyx":1005
+  /* "pywrapfst.pyx":1007
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()             # <<<<<<<<<<<<<<
@@ -11732,11 +11733,11 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw");
-    __PYX_ERR(0, 1005, __pyx_L1_error)
+    __PYX_ERR(0, 1007, __pyx_L1_error)
   }
   __pyx_v_mutable_raw = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
 
-  /* "pywrapfst.pyx":1006
+  /* "pywrapfst.pyx":1008
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
@@ -11746,7 +11747,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_t_1 = ((__pyx_v_mutable_raw == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1007
+    /* "pywrapfst.pyx":1009
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:
  *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
@@ -11755,11 +11756,11 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raise_nonexistent");
-      __PYX_ERR(0, 1007, __pyx_L1_error)
+      __PYX_ERR(0, 1009, __pyx_L1_error)
     }
-    ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._raise_nonexistent(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1007, __pyx_L1_error)
+    ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._raise_nonexistent(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1009, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1006
+    /* "pywrapfst.pyx":1008
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
@@ -11768,7 +11769,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
   }
 
-  /* "pywrapfst.pyx":1008
+  /* "pywrapfst.pyx":1010
  *     if mutable_raw == NULL:
  *       self._raise_nonexistent()
  *     return mutable_raw             # <<<<<<<<<<<<<<
@@ -11778,7 +11779,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_r = __pyx_v_mutable_raw;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1004
+  /* "pywrapfst.pyx":1006
  *   # Internal API method that should be used when a mutable pointer to an
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -11795,7 +11796,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1010
+/* "pywrapfst.pyx":1012
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
@@ -11839,10 +11840,10 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1012, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1012, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -11860,7 +11861,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1012, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11869,14 +11870,14 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1012, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1010, __pyx_L1_error)
+          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1012, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_7);
           if (__pyx_t_5) {
             __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -11887,12 +11888,12 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1012, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         }
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1010, __pyx_L1_error)
+        __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1012, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_8;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -11911,7 +11912,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1027
+  /* "pywrapfst.pyx":1029
  *       The integer key of the new symbol.
  *     """
  *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -11920,22 +11921,22 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 1027, __pyx_L1_error)
+    __PYX_ERR(0, 1029, __pyx_L1_error)
   }
-  __pyx_t_9 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1027, __pyx_L1_error)
+  __pyx_t_9 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1029, __pyx_L1_error)
   __pyx_v__mutable_raw = __pyx_t_9;
 
-  /* "pywrapfst.pyx":1028
+  /* "pywrapfst.pyx":1030
  *     """
  *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
  *     cdef string _symbol = tostring(symbol)             # <<<<<<<<<<<<<<
  *     if key != fst.kNoSymbol:
  *       return _mutable_raw.AddSymbol(_symbol, key)
  */
-  __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1030, __pyx_L1_error)
   __pyx_v__symbol = __pyx_t_10;
 
-  /* "pywrapfst.pyx":1029
+  /* "pywrapfst.pyx":1031
  *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
  *     cdef string _symbol = tostring(symbol)
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
@@ -11945,7 +11946,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
   __pyx_t_11 = ((__pyx_v_key != fst::kNoSymbol) != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1030
+    /* "pywrapfst.pyx":1032
  *     cdef string _symbol = tostring(symbol)
  *     if key != fst.kNoSymbol:
  *       return _mutable_raw.AddSymbol(_symbol, key)             # <<<<<<<<<<<<<<
@@ -11955,7 +11956,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     __pyx_r = __pyx_v__mutable_raw->AddSymbol(__pyx_v__symbol, __pyx_v_key);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1029
+    /* "pywrapfst.pyx":1031
  *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
  *     cdef string _symbol = tostring(symbol)
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
@@ -11964,7 +11965,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":1032
+  /* "pywrapfst.pyx":1034
  *       return _mutable_raw.AddSymbol(_symbol, key)
  *     else:
  *       return _mutable_raw.AddSymbol(_symbol)             # <<<<<<<<<<<<<<
@@ -11976,7 +11977,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":1010
+  /* "pywrapfst.pyx":1012
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
@@ -12038,7 +12039,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 1010, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 1012, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12051,14 +12052,14 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
     }
     __pyx_v_symbol = values[0];
     if (values[1]) {
-      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1010, __pyx_L3_error)
+      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1012, __pyx_L3_error)
     } else {
       __pyx_v_key = __pyx_k__6;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1010, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1012, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12084,8 +12085,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.key = __pyx_v_key;
-  __pyx_t_1 = __pyx_vtabptr_9pywrapfst__MutableSymbolTable->add_symbol(__pyx_v_self, __pyx_v_symbol, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1010, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
+  __pyx_t_1 = __pyx_vtabptr_9pywrapfst__MutableSymbolTable->add_symbol(__pyx_v_self, __pyx_v_symbol, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1012, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -12102,7 +12103,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1034
+/* "pywrapfst.pyx":1036
  *       return _mutable_raw.AddSymbol(_symbol)
  * 
  *   cpdef void add_table(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -12132,7 +12133,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1034, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1036, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -12148,7 +12149,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_symbols)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_symbols));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1034, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1036, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -12168,7 +12169,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":1046
+  /* "pywrapfst.pyx":1048
  *       symbols: A SymbolTable to be merged with the current table.
  *     """
  *     self._mutable_raw_ptr_or_raise().AddTable(             # <<<<<<<<<<<<<<
@@ -12177,11 +12178,11 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 1046, __pyx_L1_error)
+    __PYX_ERR(0, 1048, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1048, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1047
+  /* "pywrapfst.pyx":1049
  *     """
  *     self._mutable_raw_ptr_or_raise().AddTable(
  *         deref(symbols._raw_ptr_or_raise()))             # <<<<<<<<<<<<<<
@@ -12190,11 +12191,11 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1047, __pyx_L1_error)
+    __PYX_ERR(0, 1049, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1047, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1049, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1046
+  /* "pywrapfst.pyx":1048
  *       symbols: A SymbolTable to be merged with the current table.
  *     """
  *     self._mutable_raw_ptr_or_raise().AddTable(             # <<<<<<<<<<<<<<
@@ -12203,7 +12204,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
  */
   __pyx_t_5->AddTable((*__pyx_t_6));
 
-  /* "pywrapfst.pyx":1034
+  /* "pywrapfst.pyx":1036
  *       return _mutable_raw.AddSymbol(_symbol)
  * 
  *   cpdef void add_table(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -12233,7 +12234,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1034, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1036, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(((struct __pyx_obj_9pywrapfst__MutableSymbolTable *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -12254,8 +12255,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_symbols, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1034, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1034, __pyx_L1_error)
+  __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_symbols, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1036, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -12272,7 +12273,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1049
+/* "pywrapfst.pyx":1051
  *         deref(symbols._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -12302,7 +12303,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1049, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1051, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_5set_name)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -12318,7 +12319,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_new_name) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_new_name);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1049, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1051, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -12338,7 +12339,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":1050
+  /* "pywrapfst.pyx":1052
  * 
  *   cpdef void set_name(self, new_name) except *:
  *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))             # <<<<<<<<<<<<<<
@@ -12347,13 +12348,13 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 1050, __pyx_L1_error)
+    __PYX_ERR(0, 1052, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1050, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1050, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1052, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1052, __pyx_L1_error)
   __pyx_t_5->SetName(__pyx_t_6);
 
-  /* "pywrapfst.pyx":1049
+  /* "pywrapfst.pyx":1051
  *         deref(symbols._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -12395,8 +12396,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1049, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1049, __pyx_L1_error)
+  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1051, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1051, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -12413,7 +12414,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1060
+/* "pywrapfst.pyx":1062
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -12448,7 +12449,7 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1061
+  /* "pywrapfst.pyx":1063
  * 
  *   def __repr__(self):
  *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -12456,7 +12457,7 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
  *   cdef SymbolTable_ptr _mutable_raw(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -12466,12 +12467,12 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Fst_SymbolTableView);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 1061, __pyx_L1_error)
+    __PYX_ERR(0, 1063, __pyx_L1_error)
   }
-  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1061, __pyx_L1_error)
-  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1063, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
@@ -12483,9 +12484,9 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   __pyx_t_2 += 6;
   __Pyx_GIVEREF(__pyx_kp_u_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
-  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -12497,14 +12498,14 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1061, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1060
+  /* "pywrapfst.pyx":1062
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -12525,7 +12526,7 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1063
+/* "pywrapfst.pyx":1065
  *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12542,7 +12543,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":1064
+  /* "pywrapfst.pyx":1066
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else             # <<<<<<<<<<<<<<
@@ -12551,17 +12552,17 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1064, __pyx_L1_error)
+    __PYX_ERR(0, 1066, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1064, __pyx_L1_error)
+      __PYX_ERR(0, 1066, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->MutableInputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1065
+    /* "pywrapfst.pyx":1067
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
  *             self._mfst.get().MutableOutputSymbols())             # <<<<<<<<<<<<<<
@@ -12570,14 +12571,14 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1065, __pyx_L1_error)
+      __PYX_ERR(0, 1067, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1063
+  /* "pywrapfst.pyx":1065
  *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12594,7 +12595,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1085
+/* "pywrapfst.pyx":1087
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -12629,7 +12630,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1086
+  /* "pywrapfst.pyx":1088
  * 
  *   def __repr__(self):
  *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -12637,7 +12638,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
  *   def __init__(self, name="<unspecified>"):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -12647,12 +12648,12 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SymbolTable);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 1086, __pyx_L1_error)
+    __PYX_ERR(0, 1088, __pyx_L1_error)
   }
-  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1086, __pyx_L1_error)
-  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1088, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
@@ -12664,9 +12665,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __pyx_t_2 += 6;
   __Pyx_GIVEREF(__pyx_kp_u_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
-  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -12678,14 +12679,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1086, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1088, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1085
+  /* "pywrapfst.pyx":1087
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -12706,7 +12707,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1088
+/* "pywrapfst.pyx":1090
  *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
@@ -12746,7 +12747,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1088, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1090, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12760,7 +12761,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1088, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1090, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12782,7 +12783,7 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1089
+  /* "pywrapfst.pyx":1091
  * 
  *   def __init__(self, name="<unspecified>"):
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))             # <<<<<<<<<<<<<<
@@ -12791,12 +12792,12 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1089, __pyx_L1_error)
+    __PYX_ERR(0, 1091, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1089, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1091, __pyx_L1_error)
   __pyx_v_self->_smart_table.reset(new fst::SymbolTable(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1088
+  /* "pywrapfst.pyx":1090
  *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
@@ -12815,7 +12816,7 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1091
+/* "pywrapfst.pyx":1093
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12831,7 +12832,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__muta
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":1092
+  /* "pywrapfst.pyx":1094
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return self._smart_table.get()             # <<<<<<<<<<<<<<
@@ -12840,12 +12841,12 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__muta
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1092, __pyx_L1_error)
+    __PYX_ERR(0, 1094, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_smart_table.get();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1091
+  /* "pywrapfst.pyx":1093
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12862,7 +12863,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__muta
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1095
+/* "pywrapfst.pyx":1097
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -12899,17 +12900,17 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1110
+  /* "pywrapfst.pyx":1112
  *     """
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1110, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1112, __pyx_L1_error)
   __pyx_v__symbols.reset(fst::SymbolTable::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1111
+  /* "pywrapfst.pyx":1113
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -12919,18 +12920,18 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1112
+    /* "pywrapfst.pyx":1114
  *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1112, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1114, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1112, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1114, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1112, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -12946,14 +12947,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1112, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1114, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1112, __pyx_L1_error)
+    __PYX_ERR(0, 1114, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1111
+    /* "pywrapfst.pyx":1113
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -12962,7 +12963,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
  */
   }
 
-  /* "pywrapfst.pyx":1113
+  /* "pywrapfst.pyx":1115
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")
  *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
@@ -12970,13 +12971,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1113, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1115, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1095
+  /* "pywrapfst.pyx":1097
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -12998,7 +12999,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1116
+/* "pywrapfst.pyx":1118
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -13045,7 +13046,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 1116, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 1118, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -13058,14 +13059,14 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
     }
     __pyx_v_source = values[0];
     if (values[1]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1116, __pyx_L3_error)
+      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1118, __pyx_L3_error)
     } else {
       __pyx_v_allow_negative_labels = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1116, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1118, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -13094,7 +13095,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_text", 0);
 
-  /* "pywrapfst.pyx":1133
+  /* "pywrapfst.pyx":1135
  *     """
  *     cdef unique_ptr[fst.SymbolTableTextOptions] _opts
  *     _opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
@@ -13103,16 +13104,16 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   __pyx_v__opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
 
-  /* "pywrapfst.pyx":1135
+  /* "pywrapfst.pyx":1137
  *     _opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),             # <<<<<<<<<<<<<<
  *                                             deref(_opts)))
  *     if _symbols.get() == NULL:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1135, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1137, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1136
+  /* "pywrapfst.pyx":1138
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
  *                                             deref(_opts)))             # <<<<<<<<<<<<<<
@@ -13121,7 +13122,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   __pyx_v__symbols.reset(fst::SymbolTable::ReadText(__pyx_t_1, (*__pyx_v__opts)));
 
-  /* "pywrapfst.pyx":1137
+  /* "pywrapfst.pyx":1139
  *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
  *                                             deref(_opts)))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13131,18 +13132,18 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1138
+    /* "pywrapfst.pyx":1140
  *                                             deref(_opts)))
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1138, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1140, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1138, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1140, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1138, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1140, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -13158,14 +13159,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1140, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1138, __pyx_L1_error)
+    __PYX_ERR(0, 1140, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1137
+    /* "pywrapfst.pyx":1139
  *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
  *                                             deref(_opts)))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13174,7 +13175,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   }
 
-  /* "pywrapfst.pyx":1139
+  /* "pywrapfst.pyx":1141
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")
  *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
@@ -13182,13 +13183,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1116
+  /* "pywrapfst.pyx":1118
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -13210,7 +13211,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1142
+/* "pywrapfst.pyx":1144
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -13253,11 +13254,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_input_table)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1142, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1144, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1142, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1144, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -13266,11 +13267,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_source = values[0];
-    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1142, __pyx_L3_error)
+    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1144, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1142, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1144, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -13298,17 +13299,17 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_fst", 0);
 
-  /* "pywrapfst.pyx":1163
+  /* "pywrapfst.pyx":1165
  *     """
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))             # <<<<<<<<<<<<<<
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read from FST failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1163, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1165, __pyx_L1_error)
   __pyx_v__symbols.reset(fst::FstReadSymbols(__pyx_t_1, __pyx_v_input_table));
 
-  /* "pywrapfst.pyx":1164
+  /* "pywrapfst.pyx":1166
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13318,18 +13319,18 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1165
+    /* "pywrapfst.pyx":1167
  *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read from FST failed: {source!r}")             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1165, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1167, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1165, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1167, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_from_FST_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1165, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_from_FST_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1167, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -13345,14 +13346,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1165, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1167, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1165, __pyx_L1_error)
+    __PYX_ERR(0, 1167, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1164
+    /* "pywrapfst.pyx":1166
  *     cdef unique_ptr[fst.SymbolTable] _symbols
  *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
  *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13361,7 +13362,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
  */
   }
 
-  /* "pywrapfst.pyx":1166
+  /* "pywrapfst.pyx":1168
  *     if _symbols.get() == NULL:
  *       raise FstIOError(f"Read from FST failed: {source!r}")
  *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
@@ -13369,13 +13370,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1166, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1168, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1142
+  /* "pywrapfst.pyx":1144
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -13397,7 +13398,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1169
+/* "pywrapfst.pyx":1171
  * 
  * 
  * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13415,19 +13416,19 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1172
+  /* "pywrapfst.pyx":1174
  *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
  *   cdef _EncodeMapperSymbolTableView _symbols = (
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))             # <<<<<<<<<<<<<<
  *   _symbols._mapper = move(mapper)
  *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1172, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1174, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1173
+  /* "pywrapfst.pyx":1175
  *   cdef _EncodeMapperSymbolTableView _symbols = (
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
  *   _symbols._mapper = move(mapper)             # <<<<<<<<<<<<<<
@@ -13436,11 +13437,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1173, __pyx_L1_error)
+    __PYX_ERR(0, 1175, __pyx_L1_error)
   }
   __pyx_v__symbols->_mapper = fst::move<std::shared_ptr<fst::script::EncodeMapperClass> >(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1174
+  /* "pywrapfst.pyx":1176
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
  *   _symbols._mapper = move(mapper)
  *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
@@ -13449,11 +13450,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1174, __pyx_L1_error)
+    __PYX_ERR(0, 1176, __pyx_L1_error)
   }
   __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1175
+  /* "pywrapfst.pyx":1177
  *   _symbols._mapper = move(mapper)
  *   _symbols._input_side = input_side
  *   return _symbols             # <<<<<<<<<<<<<<
@@ -13465,7 +13466,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1169
+  /* "pywrapfst.pyx":1171
  * 
  * 
  * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13485,7 +13486,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1178
+/* "pywrapfst.pyx":1180
  * 
  * 
  * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
@@ -13503,19 +13504,19 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_FstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1181
+  /* "pywrapfst.pyx":1183
  *                                                   bool input_side):
  *   cdef _FstSymbolTableView _symbols = (
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))             # <<<<<<<<<<<<<<
  *   _symbols._fst = move(ifst)
  *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1181, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1183, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1182
+  /* "pywrapfst.pyx":1184
  *   cdef _FstSymbolTableView _symbols = (
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))
  *   _symbols._fst = move(ifst)             # <<<<<<<<<<<<<<
@@ -13524,11 +13525,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1182, __pyx_L1_error)
+    __PYX_ERR(0, 1184, __pyx_L1_error)
   }
   __pyx_v__symbols->_fst = fst::move<std::shared_ptr<fst::script::FstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1183
+  /* "pywrapfst.pyx":1185
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))
  *   _symbols._fst = move(ifst)
  *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
@@ -13537,11 +13538,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1183, __pyx_L1_error)
+    __PYX_ERR(0, 1185, __pyx_L1_error)
   }
   __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1184
+  /* "pywrapfst.pyx":1186
  *   _symbols._fst = move(ifst)
  *   _symbols._input_side = input_side
  *   return _symbols             # <<<<<<<<<<<<<<
@@ -13553,7 +13554,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
   __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1178
+  /* "pywrapfst.pyx":1180
  * 
  * 
  * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
@@ -13573,7 +13574,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1187
+/* "pywrapfst.pyx":1189
  * 
  * 
  * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13591,19 +13592,19 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_MutableFstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1191
+  /* "pywrapfst.pyx":1193
  *                                     bool input_side):
  *   cdef _MutableFstSymbolTableView _symbols = (
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))             # <<<<<<<<<<<<<<
  *   _symbols._mfst = move(ifst)
  *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1191, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1192
+  /* "pywrapfst.pyx":1194
  *   cdef _MutableFstSymbolTableView _symbols = (
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
  *   _symbols._mfst = move(ifst)             # <<<<<<<<<<<<<<
@@ -13612,11 +13613,11 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1192, __pyx_L1_error)
+    __PYX_ERR(0, 1194, __pyx_L1_error)
   }
   __pyx_v__symbols->_mfst = fst::move<std::shared_ptr<fst::script::MutableFstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1193
+  /* "pywrapfst.pyx":1195
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
  *   _symbols._mfst = move(ifst)
  *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
@@ -13625,11 +13626,11 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1193, __pyx_L1_error)
+    __PYX_ERR(0, 1195, __pyx_L1_error)
   }
   __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1194
+  /* "pywrapfst.pyx":1196
  *   _symbols._mfst = move(ifst)
  *   _symbols._input_side = input_side
  *   return _symbols             # <<<<<<<<<<<<<<
@@ -13641,7 +13642,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
   __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1187
+  /* "pywrapfst.pyx":1189
  * 
  * 
  * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13661,7 +13662,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1197
+/* "pywrapfst.pyx":1199
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):             # <<<<<<<<<<<<<<
@@ -13679,19 +13680,19 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_SymbolTable", 0);
 
-  /* "pywrapfst.pyx":1198
+  /* "pywrapfst.pyx":1200
  * 
  * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):
  *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
  *   _symbols._smart_table = move(symbols)
  *   return _symbols
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1198, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1200, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1199
+  /* "pywrapfst.pyx":1201
  * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):
  *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
  *   _symbols._smart_table = move(symbols)             # <<<<<<<<<<<<<<
@@ -13700,11 +13701,11 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
  */
   if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1199, __pyx_L1_error)
+    __PYX_ERR(0, 1201, __pyx_L1_error)
   }
   __pyx_v__symbols->_smart_table = fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_symbols);
 
-  /* "pywrapfst.pyx":1200
+  /* "pywrapfst.pyx":1202
  *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
  *   _symbols._smart_table = move(symbols)
  *   return _symbols             # <<<<<<<<<<<<<<
@@ -13716,7 +13717,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1197
+  /* "pywrapfst.pyx":1199
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):             # <<<<<<<<<<<<<<
@@ -13736,7 +13737,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1203
+/* "pywrapfst.pyx":1205
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(string state):             # <<<<<<<<<<<<<<
@@ -13759,7 +13760,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
 
-  /* "pywrapfst.pyx":1205
+  /* "pywrapfst.pyx":1207
  * cpdef SymbolTable _read_SymbolTable_from_string(string state):
  *   cdef stringstream _sstrm
  *   _sstrm << state             # <<<<<<<<<<<<<<
@@ -13768,7 +13769,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   (void)((__pyx_v__sstrm << __pyx_v_state));
 
-  /* "pywrapfst.pyx":1207
+  /* "pywrapfst.pyx":1209
  *   _sstrm << state
  *   cdef unique_ptr[fst.SymbolTable] _symbols
  *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -13777,7 +13778,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   __pyx_v__symbols.reset(fst::SymbolTable::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1208
+  /* "pywrapfst.pyx":1210
  *   cdef unique_ptr[fst.SymbolTable] _symbols
  *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13787,14 +13788,14 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
   __pyx_t_1 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1209
+    /* "pywrapfst.pyx":1211
  *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _symbols.get() == NULL:
  *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
  *   return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1209, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1211, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -13808,14 +13809,14 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1209, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1211, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 1209, __pyx_L1_error)
+    __PYX_ERR(0, 1211, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1208
+    /* "pywrapfst.pyx":1210
  *   cdef unique_ptr[fst.SymbolTable] _symbols
  *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
@@ -13824,7 +13825,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   }
 
-  /* "pywrapfst.pyx":1210
+  /* "pywrapfst.pyx":1212
  *   if _symbols.get() == NULL:
  *     raise FstIOError("Read from string failed")
  *   return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
@@ -13832,13 +13833,13 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1210, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1212, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1203
+  /* "pywrapfst.pyx":1205
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(string state):             # <<<<<<<<<<<<<<
@@ -13870,7 +13871,7 @@ static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1203, __pyx_L3_error)
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1205, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -13894,7 +13895,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1203, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1205, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13911,7 +13912,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1216
+/* "pywrapfst.pyx":1218
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -13930,7 +13931,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1228
+  /* "pywrapfst.pyx":1230
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
@@ -13939,7 +13940,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":1229
+  /* "pywrapfst.pyx":1231
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(
  *                                           deref(symbols._raw_ptr_or_raise()))))             # <<<<<<<<<<<<<<
@@ -13948,24 +13949,24 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
  */
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1229, __pyx_L1_error)
+    __PYX_ERR(0, 1231, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1229, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1231, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1228
+  /* "pywrapfst.pyx":1230
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
  *                                           deref(symbols._raw_ptr_or_raise()))))
  * 
  */
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::CompactSymbolTable((*__pyx_t_1))))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1228, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::CompactSymbolTable((*__pyx_t_1))))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1230, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1216
+  /* "pywrapfst.pyx":1218
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -13994,7 +13995,7 @@ static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compact_symbol_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1216, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1218, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10compact_symbol_table(__pyx_self, ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -14015,7 +14016,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_symbols, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1216, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_symbols, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1218, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14032,7 +14033,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1232
+/* "pywrapfst.pyx":1234
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(SymbolTableView lhs,             # <<<<<<<<<<<<<<
@@ -14052,7 +14053,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1255
+  /* "pywrapfst.pyx":1257
  *     A new merged SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
@@ -14061,7 +14062,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":1256
+  /* "pywrapfst.pyx":1258
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
  *                                           deref(lhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
@@ -14070,11 +14071,11 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1256, __pyx_L1_error)
+    __PYX_ERR(0, 1258, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_lhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_lhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1256, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_lhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_lhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1258, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1257
+  /* "pywrapfst.pyx":1259
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
  *                                           deref(lhs._raw_ptr_or_raise()),
  *                                           deref(rhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
@@ -14083,24 +14084,24 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1257, __pyx_L1_error)
+    __PYX_ERR(0, 1259, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_rhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_rhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1257, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_rhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_rhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1259, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1255
+  /* "pywrapfst.pyx":1257
  *     A new merged SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
  *                                           deref(lhs._raw_ptr_or_raise()),
  *                                           deref(rhs._raw_ptr_or_raise()),
  */
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::MergeSymbolTable((*__pyx_t_1), (*__pyx_t_2), NULL)))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::MergeSymbolTable((*__pyx_t_1), (*__pyx_t_2), NULL)))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1257, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1232
+  /* "pywrapfst.pyx":1234
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(SymbolTableView lhs,             # <<<<<<<<<<<<<<
@@ -14154,11 +14155,11 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1232, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1234, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1232, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1234, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -14171,14 +14172,14 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1232, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1234, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.merge_symbol_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "lhs", 0))) __PYX_ERR(0, 1232, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "rhs", 0))) __PYX_ERR(0, 1233, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "lhs", 0))) __PYX_ERR(0, 1234, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "rhs", 0))) __PYX_ERR(0, 1235, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12merge_symbol_table(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -14199,7 +14200,7 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1232, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1234, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14216,7 +14217,7 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1271
+/* "pywrapfst.pyx":1273
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14250,7 +14251,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1272
+  /* "pywrapfst.pyx":1274
  * 
  *   def __repr__(self):
  *     return f"<_SymbolTableIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -14258,7 +14259,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
  *   def __init__(self, SymbolTableView symbols):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1274, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -14266,9 +14267,9 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   __pyx_t_2 += 27;
   __Pyx_GIVEREF(__pyx_kp_u_SymbolTableIterator_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SymbolTableIterator_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1274, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1274, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -14280,14 +14281,14 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1274, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1271
+  /* "pywrapfst.pyx":1273
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14308,7 +14309,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1274
+/* "pywrapfst.pyx":1276
  *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -14345,7 +14346,7 @@ static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1274, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1276, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -14356,13 +14357,13 @@ static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1274, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1276, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1274, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1276, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self), __pyx_v_symbols);
 
   /* function exit code */
@@ -14383,7 +14384,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1275
+  /* "pywrapfst.pyx":1277
  * 
  *   def __init__(self, SymbolTableView symbols):
  *     self._table = symbols             # <<<<<<<<<<<<<<
@@ -14392,7 +14393,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1275, __pyx_L1_error)
+    __PYX_ERR(0, 1277, __pyx_L1_error)
   }
   __Pyx_INCREF(((PyObject *)__pyx_v_symbols));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_symbols));
@@ -14400,7 +14401,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
   __Pyx_DECREF(((PyObject *)__pyx_v_self->_table));
   __pyx_v_self->_table = __pyx_v_symbols;
 
-  /* "pywrapfst.pyx":1276
+  /* "pywrapfst.pyx":1278
  *   def __init__(self, SymbolTableView symbols):
  *     self._table = symbols
  *     self._siter.reset(             # <<<<<<<<<<<<<<
@@ -14409,10 +14410,10 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1276, __pyx_L1_error)
+    __PYX_ERR(0, 1278, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1277
+  /* "pywrapfst.pyx":1279
  *     self._table = symbols
  *     self._siter.reset(
  *         new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))             # <<<<<<<<<<<<<<
@@ -14421,15 +14422,15 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1277, __pyx_L1_error)
+    __PYX_ERR(0, 1279, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self->_table) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1277, __pyx_L1_error)
+    __PYX_ERR(0, 1279, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1277, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1279, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1276
+  /* "pywrapfst.pyx":1278
  *   def __init__(self, SymbolTableView symbols):
  *     self._table = symbols
  *     self._siter.reset(             # <<<<<<<<<<<<<<
@@ -14438,7 +14439,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
  */
   __pyx_v_self->_siter.reset(new fst::SymbolTable::iterator(__pyx_t_1->begin()));
 
-  /* "pywrapfst.pyx":1274
+  /* "pywrapfst.pyx":1276
  *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -14457,7 +14458,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1280
+/* "pywrapfst.pyx":1282
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -14483,7 +14484,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":1281
+  /* "pywrapfst.pyx":1283
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -14495,7 +14496,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1280
+  /* "pywrapfst.pyx":1282
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -14510,7 +14511,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1284
+/* "pywrapfst.pyx":1286
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -14546,7 +14547,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":1285
+  /* "pywrapfst.pyx":1287
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
@@ -14555,21 +14556,21 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1285, __pyx_L1_error)
+    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self->_table) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1285, __pyx_L1_error)
+    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1285, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1287, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1285, __pyx_L1_error)
+    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
   __pyx_t_2 = ((__pyx_t_1->end() == (*__pyx_v_self->_siter)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1286
+    /* "pywrapfst.pyx":1288
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -14577,9 +14578,9 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  *     cdef string _symbol = self._siter.get().Pair().Symbol()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 1286, __pyx_L1_error)
+    __PYX_ERR(0, 1288, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1285
+    /* "pywrapfst.pyx":1287
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
@@ -14588,7 +14589,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  */
   }
 
-  /* "pywrapfst.pyx":1287
+  /* "pywrapfst.pyx":1289
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration
  *     cdef int64 _label = self._siter.get().Pair().Label()             # <<<<<<<<<<<<<<
@@ -14597,11 +14598,11 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1287, __pyx_L1_error)
+    __PYX_ERR(0, 1289, __pyx_L1_error)
   }
   __pyx_v__label = __pyx_v_self->_siter.get()->operator*().Label();
 
-  /* "pywrapfst.pyx":1288
+  /* "pywrapfst.pyx":1290
  *       raise StopIteration
  *     cdef int64 _label = self._siter.get().Pair().Label()
  *     cdef string _symbol = self._siter.get().Pair().Symbol()             # <<<<<<<<<<<<<<
@@ -14610,11 +14611,11 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1288, __pyx_L1_error)
+    __PYX_ERR(0, 1290, __pyx_L1_error)
   }
   __pyx_v__symbol = __pyx_v_self->_siter.get()->operator*().Symbol();
 
-  /* "pywrapfst.pyx":1289
+  /* "pywrapfst.pyx":1291
  *     cdef int64 _label = self._siter.get().Pair().Label()
  *     cdef string _symbol = self._siter.get().Pair().Symbol()
  *     inc(deref(self._siter))             # <<<<<<<<<<<<<<
@@ -14623,11 +14624,11 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1289, __pyx_L1_error)
+    __PYX_ERR(0, 1291, __pyx_L1_error)
   }
   (void)((++(*__pyx_v_self->_siter)));
 
-  /* "pywrapfst.pyx":1290
+  /* "pywrapfst.pyx":1292
  *     cdef string _symbol = self._siter.get().Pair().Symbol()
  *     inc(deref(self._siter))
  *     return (_label, _symbol)             # <<<<<<<<<<<<<<
@@ -14635,11 +14636,11 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v__label); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1290, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v__label); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1292, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__symbol); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1290, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__symbol); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1292, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1290, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1292, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
@@ -14651,7 +14652,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1284
+  /* "pywrapfst.pyx":1286
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -14785,7 +14786,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1319
+/* "pywrapfst.pyx":1321
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14819,7 +14820,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1320
+  /* "pywrapfst.pyx":1322
  * 
  *   def __repr__(self):
  *     return f"<EncodeMapper at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -14827,7 +14828,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
  *   def __init__(self,
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1320, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1322, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -14835,9 +14836,9 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   __pyx_t_2 += 19;
   __Pyx_GIVEREF(__pyx_kp_u_EncodeMapper_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_EncodeMapper_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1320, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1322, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1320, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1322, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -14849,14 +14850,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1320, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1322, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1319
+  /* "pywrapfst.pyx":1321
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14877,7 +14878,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1322
+/* "pywrapfst.pyx":1324
  *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14935,7 +14936,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1322, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1324, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -14951,10 +14952,10 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
     }
     __pyx_v_arc_type = values[0];
     if (values[1]) {
-      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1324, __pyx_L3_error)
+      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1326, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1324
+      /* "pywrapfst.pyx":1326
  *   def __init__(self,
  *                arc_type="standard",
  *                bool encode_labels=False,             # <<<<<<<<<<<<<<
@@ -14964,10 +14965,10 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
       __pyx_v_encode_labels = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1325, __pyx_L3_error)
+      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1327, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1325
+      /* "pywrapfst.pyx":1327
  *                arc_type="standard",
  *                bool encode_labels=False,
  *                bool encode_weights=False):             # <<<<<<<<<<<<<<
@@ -14979,7 +14980,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1322, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1324, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14987,7 +14988,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc_type, __pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1322
+  /* "pywrapfst.pyx":1324
  *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -15015,7 +15016,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1326
+  /* "pywrapfst.pyx":1328
  *                bool encode_labels=False,
  *                bool encode_weights=False):
  *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
@@ -15024,7 +15025,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   __pyx_v__flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1327
+  /* "pywrapfst.pyx":1329
  *                bool encode_weights=False):
  *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._mapper.reset(             # <<<<<<<<<<<<<<
@@ -15033,19 +15034,19 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1327, __pyx_L1_error)
+    __PYX_ERR(0, 1329, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1328
+  /* "pywrapfst.pyx":1330
  *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._mapper.reset(
  *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))             # <<<<<<<<<<<<<<
  *     if self._mapper.get() == NULL:
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1328, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1330, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1327
+  /* "pywrapfst.pyx":1329
  *                bool encode_weights=False):
  *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._mapper.reset(             # <<<<<<<<<<<<<<
@@ -15054,7 +15055,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   __pyx_v_self->_mapper.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v__flags, fst::ENCODE));
 
-  /* "pywrapfst.pyx":1329
+  /* "pywrapfst.pyx":1331
  *     self._mapper.reset(
  *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
  *     if self._mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15063,23 +15064,23 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1329, __pyx_L1_error)
+    __PYX_ERR(0, 1331, __pyx_L1_error)
   }
   __pyx_t_2 = ((__pyx_v_self->_mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1330
+    /* "pywrapfst.pyx":1332
  *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
  *     if self._mapper.get() == NULL:
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")             # <<<<<<<<<<<<<<
  * 
  *   # Python's equivalent to operator().
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1330, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1332, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1330, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1332, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1330, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1332, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -15095,14 +15096,14 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1330, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1332, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1330, __pyx_L1_error)
+    __PYX_ERR(0, 1332, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1329
+    /* "pywrapfst.pyx":1331
  *     self._mapper.reset(
  *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
  *     if self._mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15111,7 +15112,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1322
+  /* "pywrapfst.pyx":1324
  *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -15134,7 +15135,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1334
+/* "pywrapfst.pyx":1336
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -15175,7 +15176,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1334, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1336, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -15186,13 +15187,13 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1334, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1336, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1334, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1336, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_4__call__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc);
 
   /* function exit code */
@@ -15213,7 +15214,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__call__", 0);
 
-  /* "pywrapfst.pyx":1350
+  /* "pywrapfst.pyx":1352
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     return _init_Arc(self._mapper.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
@@ -15223,19 +15224,19 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1350, __pyx_L1_error)
+    __PYX_ERR(0, 1352, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 1350, __pyx_L1_error)
+    __PYX_ERR(0, 1352, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_mapper.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1350, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_mapper.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1352, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1334
+  /* "pywrapfst.pyx":1336
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -15254,7 +15255,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1354
+/* "pywrapfst.pyx":1356
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -15286,7 +15287,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1355
+  /* "pywrapfst.pyx":1357
  * 
  *   def __reduce__(self):
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -15294,20 +15295,20 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
  *   cpdef string arc_type(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_EncodeMapper_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1355, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_EncodeMapper_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 1355, __pyx_L1_error)
+    __PYX_ERR(0, 1357, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1355, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -15319,7 +15320,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1354
+  /* "pywrapfst.pyx":1356
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -15340,7 +15341,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1357
+/* "pywrapfst.pyx":1359
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -15370,7 +15371,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1357, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1359, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15386,10 +15387,10 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1357, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1357, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1359, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15408,7 +15409,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":1363
+  /* "pywrapfst.pyx":1365
  *     Returns a string indicating the arc type.
  *     """
  *     return self._mapper.get().ArcType()             # <<<<<<<<<<<<<<
@@ -15417,12 +15418,12 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1363, __pyx_L1_error)
+    __PYX_ERR(0, 1365, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1357
+  /* "pywrapfst.pyx":1359
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -15466,7 +15467,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1357, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1359, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15483,7 +15484,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1365
+/* "pywrapfst.pyx":1367
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15513,7 +15514,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1365, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1367, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15529,10 +15530,10 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1365, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1367, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1365, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1367, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15551,7 +15552,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1371
+  /* "pywrapfst.pyx":1373
  *     Returns a string indicating the weight type.
  *     """
  *     return self._mapper.get().WeightType()             # <<<<<<<<<<<<<<
@@ -15560,12 +15561,12 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1371, __pyx_L1_error)
+    __PYX_ERR(0, 1373, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1365
+  /* "pywrapfst.pyx":1367
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15609,7 +15610,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1365, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1367, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15626,7 +15627,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1373
+/* "pywrapfst.pyx":1375
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15656,7 +15657,7 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1373, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1375, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_13flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15672,10 +15673,10 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1373, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1375, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1373, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1375, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15694,7 +15695,7 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1379
+  /* "pywrapfst.pyx":1381
  *     Returns the mapper's flags.
  *     """
  *     return self._mapper.get().Flags()             # <<<<<<<<<<<<<<
@@ -15703,12 +15704,12 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1379, __pyx_L1_error)
+    __PYX_ERR(0, 1381, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1373
+  /* "pywrapfst.pyx":1375
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15752,7 +15753,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1373, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1375, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15769,7 +15770,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1381
+/* "pywrapfst.pyx":1383
  *     return self._mapper.get().Flags()
  * 
  *   def properties(self, mask):             # <<<<<<<<<<<<<<
@@ -15804,7 +15805,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
 
-  /* "pywrapfst.pyx":1396
+  /* "pywrapfst.pyx":1398
  *     """
  * 
  *     return FstProperties(self._mapper.get().Properties(mask.value))             # <<<<<<<<<<<<<<
@@ -15812,17 +15813,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1398, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1396, __pyx_L1_error)
+    __PYX_ERR(0, 1398, __pyx_L1_error)
   }
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1398, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyInt_As_uint64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_As_uint64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1398, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_self->_mapper.get()->Properties(__pyx_t_4)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_self->_mapper.get()->Properties(__pyx_t_4)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1398, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_5 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -15837,14 +15838,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1398, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1381
+  /* "pywrapfst.pyx":1383
  *     return self._mapper.get().Flags()
  * 
  *   def properties(self, mask):             # <<<<<<<<<<<<<<
@@ -15866,7 +15867,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1399
+/* "pywrapfst.pyx":1401
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -15903,17 +15904,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1415
+  /* "pywrapfst.pyx":1417
  *     """
  *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
  *     if _mapper.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1415, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1417, __pyx_L1_error)
   __pyx_v__mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1416
+  /* "pywrapfst.pyx":1418
  *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
  *     if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15923,18 +15924,18 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   __pyx_t_2 = ((__pyx_v__mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1417
+    /* "pywrapfst.pyx":1419
  *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
  *     if _mapper.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
  *     return _init_EncodeMapper(_mapper.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1417, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1419, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1417, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1419, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1417, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1419, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -15950,14 +15951,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1417, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1419, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1417, __pyx_L1_error)
+    __PYX_ERR(0, 1419, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1416
+    /* "pywrapfst.pyx":1418
  *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
  *     if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15966,7 +15967,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
  */
   }
 
-  /* "pywrapfst.pyx":1418
+  /* "pywrapfst.pyx":1420
  *     if _mapper.get() == NULL:
  *       raise FstIOError(f"Read failed: {source!r}")
  *     return _init_EncodeMapper(_mapper.release())             # <<<<<<<<<<<<<<
@@ -15974,13 +15975,13 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
  *   @staticmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1420, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1399
+  /* "pywrapfst.pyx":1401
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -16002,7 +16003,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1421
+/* "pywrapfst.pyx":1423
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -16041,7 +16042,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UN
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1421, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1423, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -16052,7 +16053,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UN
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1421, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1423, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -16075,7 +16076,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":1436
+  /* "pywrapfst.pyx":1438
  *       FstIOError: Read failed.
  *     """
  *     return _read_EncodeMapper_from_string(state)             # <<<<<<<<<<<<<<
@@ -16083,14 +16084,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
  *   cpdef void write(self, source) except *:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1436, __pyx_L1_error)
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1438, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1438, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1421
+  /* "pywrapfst.pyx":1423
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -16109,7 +16110,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1438
+/* "pywrapfst.pyx":1440
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -16139,7 +16140,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1438, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1440, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_21write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -16155,7 +16156,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1438, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1440, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -16175,7 +16176,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1451
+  /* "pywrapfst.pyx":1453
  *         FstIOError: Write failed.
  *       """
  *       if not self._mapper.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -16184,24 +16185,24 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1451, __pyx_L1_error)
+    __PYX_ERR(0, 1453, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1451, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1453, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1452
+    /* "pywrapfst.pyx":1454
  *       """
  *       if not self._mapper.get().Write(path_tostring(source)):
  *         raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1452, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1454, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1452, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1454, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1452, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1454, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -16217,14 +16218,14 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1452, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1454, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1452, __pyx_L1_error)
+    __PYX_ERR(0, 1454, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1451
+    /* "pywrapfst.pyx":1453
  *         FstIOError: Write failed.
  *       """
  *       if not self._mapper.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -16233,7 +16234,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
  */
   }
 
-  /* "pywrapfst.pyx":1438
+  /* "pywrapfst.pyx":1440
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -16276,8 +16277,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1438, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1438, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1440, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1440, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16294,7 +16295,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1454
+/* "pywrapfst.pyx":1456
  *         raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -16325,7 +16326,7 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1454, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1456, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
@@ -16342,10 +16343,10 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1454, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1456, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1454, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1456, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16364,7 +16365,7 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1467
+  /* "pywrapfst.pyx":1469
  *       """
  *       cdef stringstream _sstrm
  *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -16373,19 +16374,19 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1467, __pyx_L1_error)
+    __PYX_ERR(0, 1469, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_v__sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1468
+    /* "pywrapfst.pyx":1470
  *       cdef stringstream _sstrm
  *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *       return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1468, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -16399,14 +16400,14 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1468, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1470, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1468, __pyx_L1_error)
+    __PYX_ERR(0, 1470, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1467
+    /* "pywrapfst.pyx":1469
  *       """
  *       cdef stringstream _sstrm
  *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -16415,7 +16416,7 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1469
+  /* "pywrapfst.pyx":1471
  *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")
  *       return _sstrm.str()             # <<<<<<<<<<<<<<
@@ -16423,13 +16424,13 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1469, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1454
+  /* "pywrapfst.pyx":1456
  *         raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -16474,7 +16475,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12EncodeMapper_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1454, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_12EncodeMapper_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16491,7 +16492,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1471
+/* "pywrapfst.pyx":1473
  *       return _sstrm.str()
  * 
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -16521,7 +16522,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1471, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1473, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -16538,10 +16539,10 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1471, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1473, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1471, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1473, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16560,7 +16561,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1477
+  /* "pywrapfst.pyx":1479
  *     Returns the mapper's input symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16569,12 +16570,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1477, __pyx_L1_error)
+    __PYX_ERR(0, 1479, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_mapper.get()->InputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1478
+    /* "pywrapfst.pyx":1480
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -16585,7 +16586,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1477
+    /* "pywrapfst.pyx":1479
  *     Returns the mapper's input symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16594,7 +16595,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1479
+  /* "pywrapfst.pyx":1481
  *     if self._mapper.get().InputSymbols() == NULL:
  *       return
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)             # <<<<<<<<<<<<<<
@@ -16604,15 +16605,15 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1479, __pyx_L1_error)
+    __PYX_ERR(0, 1481, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1479, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1481, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1471
+  /* "pywrapfst.pyx":1473
  *       return _sstrm.str()
  * 
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -16657,7 +16658,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1471, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1473, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16674,7 +16675,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1481
+/* "pywrapfst.pyx":1483
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
  *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -16704,7 +16705,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1481, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1483, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -16721,10 +16722,10 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1481, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1483, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1481, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1483, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16743,7 +16744,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1487
+  /* "pywrapfst.pyx":1489
  *     Returns the mapper's output symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16752,12 +16753,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1487, __pyx_L1_error)
+    __PYX_ERR(0, 1489, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_mapper.get()->OutputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1488
+    /* "pywrapfst.pyx":1490
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -16768,7 +16769,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1487
+    /* "pywrapfst.pyx":1489
  *     Returns the mapper's output symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16777,7 +16778,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1489
+  /* "pywrapfst.pyx":1491
  *     if self._mapper.get().OutputSymbols() == NULL:
  *       return
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)             # <<<<<<<<<<<<<<
@@ -16787,15 +16788,15 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1489, __pyx_L1_error)
+    __PYX_ERR(0, 1491, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1489, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1491, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1481
+  /* "pywrapfst.pyx":1483
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
  *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -16840,7 +16841,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1481, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1483, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16857,7 +16858,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1491
+/* "pywrapfst.pyx":1493
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -16875,7 +16876,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":1492
+  /* "pywrapfst.pyx":1494
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -16886,7 +16887,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1493
+    /* "pywrapfst.pyx":1495
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -16895,11 +16896,11 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 1493, __pyx_L1_error)
+      __PYX_ERR(0, 1495, __pyx_L1_error)
     }
     __pyx_v_self->_mapper.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":1494
+    /* "pywrapfst.pyx":1496
  *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -16908,7 +16909,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1492
+    /* "pywrapfst.pyx":1494
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -16917,7 +16918,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":1495
+  /* "pywrapfst.pyx":1497
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return
  *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
@@ -16926,16 +16927,16 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1495, __pyx_L1_error)
+    __PYX_ERR(0, 1497, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1495, __pyx_L1_error)
+    __PYX_ERR(0, 1497, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1495, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1497, __pyx_L1_error)
   __pyx_v_self->_mapper.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1491
+  /* "pywrapfst.pyx":1493
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -16951,7 +16952,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1497
+/* "pywrapfst.pyx":1499
  *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -16969,7 +16970,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1497, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1499, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -16989,7 +16990,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":1511
+  /* "pywrapfst.pyx":1513
  *       self.
  *     """
  *     self._set_input_symbols(symbols)             # <<<<<<<<<<<<<<
@@ -16998,11 +16999,11 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 1511, __pyx_L1_error)
+    __PYX_ERR(0, 1513, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1511, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1513, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1512
+  /* "pywrapfst.pyx":1514
  *     """
  *     self._set_input_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -17014,7 +17015,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1497
+  /* "pywrapfst.pyx":1499
  *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -17032,7 +17033,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1514
+/* "pywrapfst.pyx":1516
  *     return self
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -17050,7 +17051,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":1515
+  /* "pywrapfst.pyx":1517
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -17061,7 +17062,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1516
+    /* "pywrapfst.pyx":1518
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -17070,11 +17071,11 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 1516, __pyx_L1_error)
+      __PYX_ERR(0, 1518, __pyx_L1_error)
     }
     __pyx_v_self->_mapper.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":1517
+    /* "pywrapfst.pyx":1519
  *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -17083,7 +17084,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1515
+    /* "pywrapfst.pyx":1517
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -17092,7 +17093,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
  */
   }
 
-  /* "pywrapfst.pyx":1518
+  /* "pywrapfst.pyx":1520
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return
  *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
@@ -17101,16 +17102,16 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1518, __pyx_L1_error)
+    __PYX_ERR(0, 1520, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1518, __pyx_L1_error)
+    __PYX_ERR(0, 1520, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1518, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1520, __pyx_L1_error)
   __pyx_v_self->_mapper.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1514
+  /* "pywrapfst.pyx":1516
  *     return self
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -17126,7 +17127,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1520
+/* "pywrapfst.pyx":1522
  *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -17144,7 +17145,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObjec
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1520, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1522, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -17164,7 +17165,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":1534
+  /* "pywrapfst.pyx":1536
  *       self.
  *     """
  *     self._set_output_symbols(symbols)             # <<<<<<<<<<<<<<
@@ -17173,11 +17174,11 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 1534, __pyx_L1_error)
+    __PYX_ERR(0, 1536, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1534, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1536, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1535
+  /* "pywrapfst.pyx":1537
  *     """
  *     self._set_output_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -17189,7 +17190,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1520
+  /* "pywrapfst.pyx":1522
  *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -17207,7 +17208,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1538
+/* "pywrapfst.pyx":1540
  * 
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
@@ -17225,19 +17226,19 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_EncodeMapper", 0);
 
-  /* "pywrapfst.pyx":1539
+  /* "pywrapfst.pyx":1541
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)             # <<<<<<<<<<<<<<
  *   result._mapper.reset(mapper)
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_EncodeMapper(((PyTypeObject *)__pyx_ptype_9pywrapfst_EncodeMapper), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1539, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_EncodeMapper(((PyTypeObject *)__pyx_ptype_9pywrapfst_EncodeMapper), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1540
+  /* "pywrapfst.pyx":1542
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)             # <<<<<<<<<<<<<<
@@ -17246,11 +17247,11 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1540, __pyx_L1_error)
+    __PYX_ERR(0, 1542, __pyx_L1_error)
   }
   __pyx_v_result->_mapper.reset(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1541
+  /* "pywrapfst.pyx":1543
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)
  *   return result             # <<<<<<<<<<<<<<
@@ -17262,7 +17263,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1538
+  /* "pywrapfst.pyx":1540
  * 
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
@@ -17282,7 +17283,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1544
+/* "pywrapfst.pyx":1546
  * 
  * 
  * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):             # <<<<<<<<<<<<<<
@@ -17305,7 +17306,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
 
-  /* "pywrapfst.pyx":1546
+  /* "pywrapfst.pyx":1548
  * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):
  *   cdef stringstream _sstrm
  *   _sstrm << state             # <<<<<<<<<<<<<<
@@ -17314,7 +17315,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  */
   (void)((__pyx_v__sstrm << __pyx_v_state));
 
-  /* "pywrapfst.pyx":1548
+  /* "pywrapfst.pyx":1550
  *   _sstrm << state
  *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -17323,7 +17324,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  */
   __pyx_v__mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1549
+  /* "pywrapfst.pyx":1551
  *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -17333,14 +17334,14 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
   __pyx_t_1 = ((__pyx_v__mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1550
+    /* "pywrapfst.pyx":1552
  *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _mapper.get() == NULL:
  *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
  *   return _init_EncodeMapper(_mapper.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1550, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1552, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -17354,14 +17355,14 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1550, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 1550, __pyx_L1_error)
+    __PYX_ERR(0, 1552, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1549
+    /* "pywrapfst.pyx":1551
  *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
  *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -17370,7 +17371,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  */
   }
 
-  /* "pywrapfst.pyx":1551
+  /* "pywrapfst.pyx":1553
  *   if _mapper.get() == NULL:
  *     raise FstIOError("Read from string failed")
  *   return _init_EncodeMapper(_mapper.release())             # <<<<<<<<<<<<<<
@@ -17378,13 +17379,13 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1551, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1553, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1544
+  /* "pywrapfst.pyx":1546
  * 
  * 
  * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):             # <<<<<<<<<<<<<<
@@ -17416,7 +17417,7 @@ static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1544, __pyx_L3_error)
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1546, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -17440,7 +17441,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1544, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1546, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17457,7 +17458,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1577
+/* "pywrapfst.pyx":1579
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17479,77 +17480,77 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_local_render_svg", 0);
 
-  /* "pywrapfst.pyx":1578
+  /* "pywrapfst.pyx":1580
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1579
+  /* "pywrapfst.pyx":1581
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,             # <<<<<<<<<<<<<<
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1579, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1581, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1579, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1581, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1579, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1581, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1579, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1581, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":1580
+  /* "pywrapfst.pyx":1582
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)             # <<<<<<<<<<<<<<
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1580, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1582, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1580, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1582, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1579, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1581, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1578
+  /* "pywrapfst.pyx":1580
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_proc = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1581
+  /* "pywrapfst.pyx":1583
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]             # <<<<<<<<<<<<<<
  * 
  *   def _repr_svg_(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1581, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1581, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1581, __pyx_L1_error)
+  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -17565,22 +17566,22 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   __pyx_t_3 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1581, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(__pyx_t_3 == Py_None)) {
     PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
-    __PYX_ERR(0, 1581, __pyx_L1_error)
+    __PYX_ERR(0, 1583, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1581, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1581, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1583, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1577
+  /* "pywrapfst.pyx":1579
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17602,7 +17603,7 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1583
+/* "pywrapfst.pyx":1585
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17654,7 +17655,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_repr_svg_", 0);
 
-  /* "pywrapfst.pyx":1591
+  /* "pywrapfst.pyx":1593
  *     """
  *     cdef stringstream _sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
@@ -17663,10 +17664,10 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1591, __pyx_L1_error)
+    __PYX_ERR(0, 1593, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1592
+  /* "pywrapfst.pyx":1594
  *     cdef stringstream _sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)             # <<<<<<<<<<<<<<
@@ -17675,7 +17676,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   __pyx_v_acceptor = (__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor);
 
-  /* "pywrapfst.pyx":1593
+  /* "pywrapfst.pyx":1595
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -17684,10 +17685,10 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1593, __pyx_L1_error)
+    __PYX_ERR(0, 1595, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1594
+  /* "pywrapfst.pyx":1596
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst),
  *              self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
@@ -17696,10 +17697,10 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1594, __pyx_L1_error)
+    __PYX_ERR(0, 1596, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1595
+  /* "pywrapfst.pyx":1597
  *     fst.Draw(deref(self._fst),
  *              self._fst.get().InputSymbols(),
  *              self._fst.get().OutputSymbols(),             # <<<<<<<<<<<<<<
@@ -17708,10 +17709,10 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1595, __pyx_L1_error)
+    __PYX_ERR(0, 1597, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1593
+  /* "pywrapfst.pyx":1595
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -17720,7 +17721,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  */
   fst::script::Draw((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, __pyx_v_acceptor, __pyx_k__11, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_k_g, 0, __pyx_v__sstrm, __pyx_k_pywrapfst);
 
-  /* "pywrapfst.pyx":1611
+  /* "pywrapfst.pyx":1613
  *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
@@ -17736,7 +17737,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":1612
+      /* "pywrapfst.pyx":1614
  *              b"<pywrapfst>")
  *     try:
  *       return Fst._local_render_svg(_sstrm.str())             # <<<<<<<<<<<<<<
@@ -17744,13 +17745,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
  *       logging.error("Dot rendering failed: %s", e)
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst__local_render_svg(__pyx_v__sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1612, __pyx_L3_error)
+      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst__local_render_svg(__pyx_v__sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1614, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_r = __pyx_t_4;
       __pyx_t_4 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":1611
+      /* "pywrapfst.pyx":1613
  *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
@@ -17761,7 +17762,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":1613
+    /* "pywrapfst.pyx":1615
  *     try:
  *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
@@ -17771,7 +17772,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_5) {
       __Pyx_AddTraceback("pywrapfst.Fst._repr_svg_", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1613, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1615, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_GOTREF(__pyx_t_7);
@@ -17779,16 +17780,16 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
       __pyx_v_e = __pyx_t_6;
       /*try:*/ {
 
-        /* "pywrapfst.pyx":1614
+        /* "pywrapfst.pyx":1616
  *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:
  *       logging.error("Dot rendering failed: %s", e)             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self):
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1614, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1616, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1614, __pyx_L14_error)
+        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1616, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_9 = NULL;
@@ -17806,7 +17807,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1614, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1616, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
@@ -17814,13 +17815,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1614, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1616, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
         #endif
         {
-          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1614, __pyx_L14_error)
+          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1616, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_11);
           if (__pyx_t_9) {
             __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL;
@@ -17831,7 +17832,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
           __Pyx_INCREF(__pyx_v_e);
           __Pyx_GIVEREF(__pyx_v_e);
           PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_5, __pyx_v_e);
-          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1614, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1616, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         }
@@ -17839,7 +17840,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
 
-      /* "pywrapfst.pyx":1613
+      /* "pywrapfst.pyx":1615
  *     try:
  *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
@@ -17898,7 +17899,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":1611
+    /* "pywrapfst.pyx":1613
  *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
@@ -17923,7 +17924,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "pywrapfst.pyx":1583
+  /* "pywrapfst.pyx":1585
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17951,7 +17952,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1616
+/* "pywrapfst.pyx":1618
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -17985,32 +17986,32 @@ static int __pyx_pf_9pywrapfst_3Fst_2__init__(struct __pyx_obj_9pywrapfst_Fst *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1617
+  /* "pywrapfst.pyx":1619
  * 
  *   def __init__(self):
  *     raise NotImplementedError(f"Cannot construct {self._class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   # Registers the class for pickling; must be repeated in any subclass which
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 1617, __pyx_L1_error)
+  __PYX_ERR(0, 1619, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1616
+  /* "pywrapfst.pyx":1618
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -18028,7 +18029,7 @@ static int __pyx_pf_9pywrapfst_3Fst_2__init__(struct __pyx_obj_9pywrapfst_Fst *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1622
+/* "pywrapfst.pyx":1624
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -18060,7 +18061,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1623
+  /* "pywrapfst.pyx":1625
  * 
  *   def __reduce__(self):
  *     return (_read_Fst_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -18068,20 +18069,20 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
  *   def __repr__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1623, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1625, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 1623, __pyx_L1_error)
+    __PYX_ERR(0, 1625, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1623, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1625, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1623, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1625, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1623, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1625, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -18093,7 +18094,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1622
+  /* "pywrapfst.pyx":1624
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -18114,7 +18115,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1625
+/* "pywrapfst.pyx":1627
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -18148,7 +18149,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1626
+  /* "pywrapfst.pyx":1628
  * 
  *   def __repr__(self):
  *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -18156,7 +18157,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
  *   def __str__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1626, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1628, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -18166,9 +18167,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "fst_type");
-    __PYX_ERR(0, 1626, __pyx_L1_error)
+    __PYX_ERR(0, 1628, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1626, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1628, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
   __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -18179,9 +18180,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   __pyx_t_2 += 10;
   __Pyx_GIVEREF(__pyx_kp_u_Fst_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_Fst_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1626, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1628, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1626, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1628, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -18193,14 +18194,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1626, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1628, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1625
+  /* "pywrapfst.pyx":1627
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -18221,7 +18222,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1628
+/* "pywrapfst.pyx":1630
  *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -18252,7 +18253,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":1629
+  /* "pywrapfst.pyx":1631
  * 
  *   def __str__(self):
  *     return self.print()             # <<<<<<<<<<<<<<
@@ -18262,16 +18263,16 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "print");
-    __PYX_ERR(0, 1629, __pyx_L1_error)
+    __PYX_ERR(0, 1631, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->print(__pyx_v_self, 0, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1629, __pyx_L1_error)
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1629, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->print(__pyx_v_self, 0, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1631, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1631, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1628
+  /* "pywrapfst.pyx":1630
  *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -18290,7 +18291,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1631
+/* "pywrapfst.pyx":1633
  *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -18320,7 +18321,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1631, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1633, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_11arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -18336,10 +18337,10 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1631, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1633, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1631, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1633, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18358,21 +18359,21 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1637
+  /* "pywrapfst.pyx":1639
  *     Returns a string indicating the arc type.
  *     """
  *     return self._fst.get().ArcType()             # <<<<<<<<<<<<<<
  * 
- *   cpdef ArcIterator arcs(self, int64 state):
+ *   cpdef _ArcIterator arcs(self, int64 state):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1637, __pyx_L1_error)
+    __PYX_ERR(0, 1639, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1631
+  /* "pywrapfst.pyx":1633
  *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -18416,7 +18417,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1631, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1633, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18433,17 +18434,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1639
+/* "pywrapfst.pyx":1641
  *     return self._fst.get().ArcType()
  * 
- *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
+ *   cpdef _ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
  *     arcs(self, state)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -18463,11 +18464,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1639, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1641, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_13arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1639, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1641, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18483,11 +18484,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1639, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1641, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1639, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__ArcIterator))))) __PYX_ERR(0, 1641, __pyx_L1_error)
+        __pyx_r = ((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         goto __pyx_L0;
@@ -18505,17 +18506,17 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
     #endif
   }
 
-  /* "pywrapfst.pyx":1651
- *       An ArcIterator.
+  /* "pywrapfst.pyx":1653
+ *       An _ArcIterator.
  *     """
- *     return ArcIterator(self, state)             # <<<<<<<<<<<<<<
+ *     return _ArcIterator(self, state)             # <<<<<<<<<<<<<<
  * 
  *   cpdef Fst copy(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1651, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1653, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1651, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1653, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -18523,17 +18524,17 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1651, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst__ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1653, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1639
+  /* "pywrapfst.pyx":1641
  *     return self._fst.get().ArcType()
  * 
- *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
+ *   cpdef _ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
  *     arcs(self, state)
  */
@@ -18555,7 +18556,7 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_12arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An ArcIterator.\n    ";
+static char __pyx_doc_9pywrapfst_3Fst_12arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An _ArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
   int __pyx_lineno = 0;
@@ -18565,7 +18566,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObjec
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1639, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1641, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -18589,7 +18590,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1639, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1641, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18606,8 +18607,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1653
- *     return ArcIterator(self, state)
+/* "pywrapfst.pyx":1655
+ *     return _ArcIterator(self, state)
  * 
  *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -18635,7 +18636,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1653, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1655, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_15copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -18652,10 +18653,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1653, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1655, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 1653, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 1655, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18674,7 +18675,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":1659
+  /* "pywrapfst.pyx":1661
  *     Makes a copy of the FST.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -18684,16 +18685,16 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1659, __pyx_L1_error)
+    __PYX_ERR(0, 1661, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1659, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1661, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1653
- *     return ArcIterator(self, state)
+  /* "pywrapfst.pyx":1655
+ *     return _ArcIterator(self, state)
  * 
  *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -18737,7 +18738,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1653, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1655, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18754,7 +18755,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1661
+/* "pywrapfst.pyx":1663
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18765,7 +18766,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst
 static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":1663
+  /* "pywrapfst.pyx":1665
  *   cpdef void draw(self,
  *                   source,
  *                   SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -18774,7 +18775,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1664
+  /* "pywrapfst.pyx":1666
  *                   source,
  *                   SymbolTableView isymbols=None,
  *                   SymbolTableView osymbols=None,             # <<<<<<<<<<<<<<
@@ -18783,7 +18784,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1665
+  /* "pywrapfst.pyx":1667
  *                   SymbolTableView isymbols=None,
  *                   SymbolTableView osymbols=None,
  *                   SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
@@ -18792,7 +18793,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1666
+  /* "pywrapfst.pyx":1668
  *                   SymbolTableView osymbols=None,
  *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -18804,7 +18805,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   double __pyx_v_width = ((double)8.5);
   double __pyx_v_height = ((double)11.0);
 
-  /* "pywrapfst.pyx":1670
+  /* "pywrapfst.pyx":1672
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -18813,7 +18814,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   bool __pyx_v_portrait = ((bool)0);
 
-  /* "pywrapfst.pyx":1671
+  /* "pywrapfst.pyx":1673
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -18827,7 +18828,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   int32 __pyx_v_precision = ((int32)5);
   PyObject *__pyx_v_float_format = ((PyObject *)__pyx_n_u_g);
 
-  /* "pywrapfst.pyx":1677
+  /* "pywrapfst.pyx":1679
  *                   int32 precision=5,
  *                   float_format="g",
  *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
@@ -18914,7 +18915,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     }
   }
 
-  /* "pywrapfst.pyx":1661
+  /* "pywrapfst.pyx":1663
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18930,28 +18931,28 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1661, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1663, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_17draw)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
-        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1661, __pyx_L1_error)
+        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1663, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_13 = __pyx_t_1; __pyx_t_14 = NULL;
@@ -18969,7 +18970,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_13)) {
           PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1661, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1663, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -18987,7 +18988,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_13)) {
           PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1661, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1663, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -19003,7 +19004,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         } else
         #endif
         {
-          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1661, __pyx_L1_error)
+          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1663, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_16);
           if (__pyx_t_14) {
             __Pyx_GIVEREF(__pyx_t_14); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_14); __pyx_t_14 = NULL;
@@ -19056,7 +19057,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
           __pyx_t_10 = 0;
           __pyx_t_11 = 0;
           __pyx_t_12 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1661, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1663, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         }
@@ -19078,17 +19079,17 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1709
+  /* "pywrapfst.pyx":1711
  *       show_weight_one: Should weights equivalent to semiring One be printed?
  *     """
  *     cdef string _source = path_tostring(source)             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[ostream] _fstrm
  *     _fstrm.reset(new ofstream(_source))
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1709, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1711, __pyx_L1_error)
   __pyx_v__source = __pyx_t_17;
 
-  /* "pywrapfst.pyx":1711
+  /* "pywrapfst.pyx":1713
  *     cdef string _source = path_tostring(source)
  *     cdef unique_ptr[ostream] _fstrm
  *     _fstrm.reset(new ofstream(_source))             # <<<<<<<<<<<<<<
@@ -19097,7 +19098,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   __pyx_v__fstrm.reset(new std::ofstream(__pyx_v__source));
 
-  /* "pywrapfst.pyx":1712
+  /* "pywrapfst.pyx":1714
  *     cdef unique_ptr[ostream] _fstrm
  *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
@@ -19106,11 +19107,11 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1712, __pyx_L1_error)
+    __PYX_ERR(0, 1714, __pyx_L1_error)
   }
   __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1713
+  /* "pywrapfst.pyx":1715
  *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -19121,7 +19122,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1714
+    /* "pywrapfst.pyx":1716
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -19130,12 +19131,12 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1714, __pyx_L1_error)
+      __PYX_ERR(0, 1716, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1714, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1716, __pyx_L1_error)
     __pyx_v__isymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1713
+    /* "pywrapfst.pyx":1715
  *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -19144,7 +19145,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1715
+  /* "pywrapfst.pyx":1717
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -19153,11 +19154,11 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1715, __pyx_L1_error)
+    __PYX_ERR(0, 1717, __pyx_L1_error)
   }
   __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1716
+  /* "pywrapfst.pyx":1718
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -19168,7 +19169,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_18 = (__pyx_t_19 != 0);
   if (__pyx_t_18) {
 
-    /* "pywrapfst.pyx":1717
+    /* "pywrapfst.pyx":1719
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -19177,12 +19178,12 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1717, __pyx_L1_error)
+      __PYX_ERR(0, 1719, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1717, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1719, __pyx_L1_error)
     __pyx_v__osymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1716
+    /* "pywrapfst.pyx":1718
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -19191,7 +19192,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1718
+  /* "pywrapfst.pyx":1720
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -19200,7 +19201,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   __pyx_v__ssymbols = NULL;
 
-  /* "pywrapfst.pyx":1719
+  /* "pywrapfst.pyx":1721
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -19211,7 +19212,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1720
+    /* "pywrapfst.pyx":1722
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -19220,12 +19221,12 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1720, __pyx_L1_error)
+      __PYX_ERR(0, 1722, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1720, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1722, __pyx_L1_error)
     __pyx_v__ssymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1719
+    /* "pywrapfst.pyx":1721
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -19234,7 +19235,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1721
+  /* "pywrapfst.pyx":1723
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -19243,28 +19244,28 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1721, __pyx_L1_error)
+    __PYX_ERR(0, 1723, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1726
+  /* "pywrapfst.pyx":1728
  *              _ssymbols,
  *              acceptor,
  *              tostring(title),             # <<<<<<<<<<<<<<
  *              width,
  *              height,
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1726, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1728, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1735
+  /* "pywrapfst.pyx":1737
  *              fontsize,
  *              precision,
  *              tostring(float_format),             # <<<<<<<<<<<<<<
  *              show_weight_one,
  *              deref(_fstrm),
  */
-  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1735, __pyx_L1_error)
+  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1737, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1721
+  /* "pywrapfst.pyx":1723
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -19273,7 +19274,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   fst::script::Draw((*__pyx_v_self->_fst), __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_t_17, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_t_21, __pyx_v_show_weight_one, (*__pyx_v__fstrm), __pyx_v__source);
 
-  /* "pywrapfst.pyx":1661
+  /* "pywrapfst.pyx":1663
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -19334,7 +19335,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_title,&__pyx_n_s_width,&__pyx_n_s_height,&__pyx_n_s_portrait,&__pyx_n_s_vertical,&__pyx_n_s_ranksep,&__pyx_n_s_nodesep,&__pyx_n_s_fontsize,&__pyx_n_s_precision,&__pyx_n_s_float_format,&__pyx_n_s_show_weight_one,0};
     PyObject* values[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":1663
+    /* "pywrapfst.pyx":1665
  *   cpdef void draw(self,
  *                   source,
  *                   SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -19343,7 +19344,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1664
+    /* "pywrapfst.pyx":1666
  *                   source,
  *                   SymbolTableView isymbols=None,
  *                   SymbolTableView osymbols=None,             # <<<<<<<<<<<<<<
@@ -19352,7 +19353,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1665
+    /* "pywrapfst.pyx":1667
  *                   SymbolTableView isymbols=None,
  *                   SymbolTableView osymbols=None,
  *                   SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
@@ -19498,7 +19499,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1661, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1663, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -19542,10 +19543,10 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[2]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[3]);
     if (values[4]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1666, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1668, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1666
+      /* "pywrapfst.pyx":1668
  *                   SymbolTableView osymbols=None,
  *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -19556,20 +19557,20 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
     }
     __pyx_v_title = values[5];
     if (values[6]) {
-      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1668, __pyx_L3_error)
+      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1670, __pyx_L3_error)
     } else {
       __pyx_v_width = ((double)8.5);
     }
     if (values[7]) {
-      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1669, __pyx_L3_error)
+      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1671, __pyx_L3_error)
     } else {
       __pyx_v_height = ((double)11.0);
     }
     if (values[8]) {
-      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1670, __pyx_L3_error)
+      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1672, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1670
+      /* "pywrapfst.pyx":1672
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -19579,10 +19580,10 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
       __pyx_v_portrait = ((bool)0);
     }
     if (values[9]) {
-      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1671, __pyx_L3_error)
+      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1673, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1671
+      /* "pywrapfst.pyx":1673
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -19592,31 +19593,31 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
       __pyx_v_vertical = ((bool)0);
     }
     if (values[10]) {
-      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1672, __pyx_L3_error)
+      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1674, __pyx_L3_error)
     } else {
       __pyx_v_ranksep = ((double)0.4);
     }
     if (values[11]) {
-      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1673, __pyx_L3_error)
+      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1675, __pyx_L3_error)
     } else {
       __pyx_v_nodesep = ((double)0.25);
     }
     if (values[12]) {
-      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1674, __pyx_L3_error)
+      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1676, __pyx_L3_error)
     } else {
       __pyx_v_fontsize = ((int32)14);
     }
     if (values[13]) {
-      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1675, __pyx_L3_error)
+      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1677, __pyx_L3_error)
     } else {
       __pyx_v_precision = ((int32)5);
     }
     __pyx_v_float_format = values[14];
     if (values[15]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1677, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1679, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1677
+      /* "pywrapfst.pyx":1679
  *                   int32 precision=5,
  *                   float_format="g",
  *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
@@ -19628,18 +19629,18 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1661, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1663, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1663, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1664, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1665, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1665, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1666, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1667, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_3Fst_16draw(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_source, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_title, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_v_float_format, __pyx_v_show_weight_one);
 
-  /* "pywrapfst.pyx":1661
+  /* "pywrapfst.pyx":1663
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -19682,8 +19683,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_1.precision = __pyx_v_precision;
   __pyx_t_1.float_format = __pyx_v_float_format;
   __pyx_t_1.show_weight_one = __pyx_v_show_weight_one;
-  __pyx_vtabptr_9pywrapfst_Fst->draw(__pyx_v_self, __pyx_v_source, 1, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1661, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1661, __pyx_L1_error)
+  __pyx_vtabptr_9pywrapfst_Fst->draw(__pyx_v_self, __pyx_v_source, 1, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1663, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1663, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19700,7 +19701,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1740
+/* "pywrapfst.pyx":1742
  *              _source)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -19732,11 +19733,11 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1740, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1742, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_19final)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1740, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1742, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19752,10 +19753,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1740, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1742, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1740, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1742, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19774,19 +19775,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":1755
+  /* "pywrapfst.pyx":1757
  *       FstIndexError: State index out of range.
  *     """
  *     cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not _weight.member():
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1755, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1757, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1756
+  /* "pywrapfst.pyx":1758
  *     """
  *     cdef Weight _weight = Weight.__new__(Weight)
  *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
@@ -19795,15 +19796,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 1756, __pyx_L1_error)
+    __PYX_ERR(0, 1758, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1756, __pyx_L1_error)
+    __PYX_ERR(0, 1758, __pyx_L1_error)
   }
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
 
-  /* "pywrapfst.pyx":1757
+  /* "pywrapfst.pyx":1759
  *     cdef Weight _weight = Weight.__new__(Weight)
  *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not _weight.member():             # <<<<<<<<<<<<<<
@@ -19812,19 +19813,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 1757, __pyx_L1_error)
+    __PYX_ERR(0, 1759, __pyx_L1_error)
   }
   __pyx_t_6 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->member(__pyx_v__weight, 0) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1758
+    /* "pywrapfst.pyx":1760
  *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not _weight.member():
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1758, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1760, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19838,14 +19839,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1758, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1760, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1758, __pyx_L1_error)
+    __PYX_ERR(0, 1760, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1757
+    /* "pywrapfst.pyx":1759
  *     cdef Weight _weight = Weight.__new__(Weight)
  *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not _weight.member():             # <<<<<<<<<<<<<<
@@ -19854,7 +19855,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
  */
   }
 
-  /* "pywrapfst.pyx":1759
+  /* "pywrapfst.pyx":1761
  *     if not _weight.member():
  *       raise FstIndexError("State index out of range")
  *     return _weight             # <<<<<<<<<<<<<<
@@ -19866,7 +19867,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
   __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1740
+  /* "pywrapfst.pyx":1742
  *              _source)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -19902,7 +19903,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_19final(PyObject *__pyx_v_self, PyObje
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("final (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1740, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1742, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19926,7 +19927,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("final", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1740, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1742, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19943,7 +19944,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1761
+/* "pywrapfst.pyx":1763
  *     return _weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -19973,7 +19974,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1761, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1763, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_21fst_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -19989,10 +19990,10 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1761, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1763, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1761, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1763, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20011,7 +20012,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1767
+  /* "pywrapfst.pyx":1769
  *     Returns a string indicating the FST type.
  *     """
  *     return self._fst.get().FstType()             # <<<<<<<<<<<<<<
@@ -20020,12 +20021,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1767, __pyx_L1_error)
+    __PYX_ERR(0, 1769, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->FstType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1761
+  /* "pywrapfst.pyx":1763
  *     return _weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -20069,7 +20070,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("fst_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1761, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1763, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20086,7 +20087,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1769
+/* "pywrapfst.pyx":1771
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -20116,7 +20117,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1769, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1771, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_23input_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -20133,10 +20134,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1769, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1771, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1769, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1771, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20155,7 +20156,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1775
+  /* "pywrapfst.pyx":1777
  *     Returns the FST's input symbol table, or None if none is present.
  *     """
  *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -20164,12 +20165,12 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1775, __pyx_L1_error)
+    __PYX_ERR(0, 1777, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_fst.get()->InputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1776
+    /* "pywrapfst.pyx":1778
  *     """
  *     if self._fst.get().InputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -20180,7 +20181,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1775
+    /* "pywrapfst.pyx":1777
  *     Returns the FST's input symbol table, or None if none is present.
  *     """
  *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -20189,7 +20190,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
  */
   }
 
-  /* "pywrapfst.pyx":1777
+  /* "pywrapfst.pyx":1779
  *     if self._fst.get().InputSymbols() == NULL:
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=True)             # <<<<<<<<<<<<<<
@@ -20199,15 +20200,15 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1777, __pyx_L1_error)
+    __PYX_ERR(0, 1779, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1777, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1779, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1769
+  /* "pywrapfst.pyx":1771
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -20252,7 +20253,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1769, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1771, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20269,7 +20270,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1779
+/* "pywrapfst.pyx":1781
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20302,10 +20303,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1779, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1781, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_25num_arcs)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1779, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1781, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20321,10 +20322,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1779, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1781, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1779, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1781, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20343,7 +20344,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     #endif
   }
 
-  /* "pywrapfst.pyx":1794
+  /* "pywrapfst.pyx":1796
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t _result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
@@ -20352,11 +20353,11 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1794, __pyx_L1_error)
+    __PYX_ERR(0, 1796, __pyx_L1_error)
   }
   __pyx_v__result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1795
+  /* "pywrapfst.pyx":1797
  *     """
  *     cdef size_t _result = self._fst.get().NumArcs(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20366,14 +20367,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
   __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1796
+    /* "pywrapfst.pyx":1798
  *     cdef size_t _result = self._fst.get().NumArcs(state)
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1796, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1798, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20387,14 +20388,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1796, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1798, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1796, __pyx_L1_error)
+    __PYX_ERR(0, 1798, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1795
+    /* "pywrapfst.pyx":1797
  *     """
  *     cdef size_t _result = self._fst.get().NumArcs(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20403,7 +20404,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
  */
   }
 
-  /* "pywrapfst.pyx":1797
+  /* "pywrapfst.pyx":1799
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return _result             # <<<<<<<<<<<<<<
@@ -20413,7 +20414,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
   __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1779
+  /* "pywrapfst.pyx":1781
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20447,7 +20448,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_25num_arcs(PyObject *__pyx_v_self, PyO
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1779, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1781, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20472,8 +20473,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1779, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1779, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1781, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1781, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20490,7 +20491,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1799
+/* "pywrapfst.pyx":1801
  *     return _result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20523,10 +20524,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1799, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1801, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1799, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1801, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20542,10 +20543,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1799, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1801, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1799, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1801, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20564,7 +20565,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":1814
+  /* "pywrapfst.pyx":1816
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -20573,11 +20574,11 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1814, __pyx_L1_error)
+    __PYX_ERR(0, 1816, __pyx_L1_error)
   }
   __pyx_v__result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1815
+  /* "pywrapfst.pyx":1817
  *     """
  *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20587,14 +20588,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
   __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1816
+    /* "pywrapfst.pyx":1818
  *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1816, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1818, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20608,14 +20609,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1816, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1818, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1816, __pyx_L1_error)
+    __PYX_ERR(0, 1818, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1815
+    /* "pywrapfst.pyx":1817
  *     """
  *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20624,7 +20625,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
  */
   }
 
-  /* "pywrapfst.pyx":1817
+  /* "pywrapfst.pyx":1819
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return _result             # <<<<<<<<<<<<<<
@@ -20634,7 +20635,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
   __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1799
+  /* "pywrapfst.pyx":1801
  *     return _result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20668,7 +20669,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons(PyObject *__pyx_v
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_input_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1799, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1801, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20693,8 +20694,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_input_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1799, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1799, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1801, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1801, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20711,7 +20712,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1819
+/* "pywrapfst.pyx":1821
  *     return _result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20744,10 +20745,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1819, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1821, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1819, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1821, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20763,10 +20764,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1819, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1821, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1819, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1821, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20785,7 +20786,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1834
+  /* "pywrapfst.pyx":1836
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -20794,11 +20795,11 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1834, __pyx_L1_error)
+    __PYX_ERR(0, 1836, __pyx_L1_error)
   }
   __pyx_v__result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1835
+  /* "pywrapfst.pyx":1837
  *     """
  *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20808,14 +20809,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
   __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1836
+    /* "pywrapfst.pyx":1838
  *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1836, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1838, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20829,14 +20830,14 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1836, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1838, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1836, __pyx_L1_error)
+    __PYX_ERR(0, 1838, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1835
+    /* "pywrapfst.pyx":1837
  *     """
  *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
  *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20845,7 +20846,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1837
+  /* "pywrapfst.pyx":1839
  *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return _result             # <<<<<<<<<<<<<<
@@ -20855,7 +20856,7 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
   __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1819
+  /* "pywrapfst.pyx":1821
  *     return _result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20889,7 +20890,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons(PyObject *__pyx_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_output_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1819, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1821, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20914,8 +20915,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_output_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1819, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1819, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1821, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1821, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20932,7 +20933,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1839
+/* "pywrapfst.pyx":1841
  *     return _result
  * 
  *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -20962,7 +20963,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1839, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1841, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_31output_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -20979,10 +20980,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1839, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1841, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1839, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1841, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21001,7 +21002,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1845
+  /* "pywrapfst.pyx":1847
  *     Returns the FST's output symbol table, or None if none is present.
  *     """
  *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -21010,12 +21011,12 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1845, __pyx_L1_error)
+    __PYX_ERR(0, 1847, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_fst.get()->OutputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1846
+    /* "pywrapfst.pyx":1848
  *     """
  *     if self._fst.get().OutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -21026,7 +21027,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1845
+    /* "pywrapfst.pyx":1847
  *     Returns the FST's output symbol table, or None if none is present.
  *     """
  *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -21035,7 +21036,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
  */
   }
 
-  /* "pywrapfst.pyx":1847
+  /* "pywrapfst.pyx":1849
  *     if self._fst.get().OutputSymbols() == NULL:
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=False)             # <<<<<<<<<<<<<<
@@ -21045,15 +21046,15 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1847, __pyx_L1_error)
+    __PYX_ERR(0, 1849, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1847, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1849, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1839
+  /* "pywrapfst.pyx":1841
  *     return _result
  * 
  *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -21098,7 +21099,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1839, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1841, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21115,7 +21116,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1849
+/* "pywrapfst.pyx":1851
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -21127,7 +21128,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
 static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args) {
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1850
+  /* "pywrapfst.pyx":1852
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,
  *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
@@ -21137,7 +21138,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1851
+  /* "pywrapfst.pyx":1853
  *   cpdef string print(self, SymbolTableView isymbols=None,
  *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,             # <<<<<<<<<<<<<<
@@ -21190,7 +21191,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     }
   }
 
-  /* "pywrapfst.pyx":1849
+  /* "pywrapfst.pyx":1851
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -21206,12 +21207,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_print); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1849, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_print); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1851, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_33print)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1849, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1851, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1849, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1851, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -21229,7 +21230,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1849, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1851, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -21239,7 +21240,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1849, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1851, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -21247,7 +21248,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1849, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1851, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -21270,12 +21271,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
           PyTuple_SET_ITEM(__pyx_t_8, 5+__pyx_t_7, __pyx_v_missing_sym);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1849, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1851, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1849, __pyx_L1_error)
+        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1851, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_9;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21294,7 +21295,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1875
+  /* "pywrapfst.pyx":1877
  *     """
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
@@ -21303,11 +21304,11 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1875, __pyx_L1_error)
+    __PYX_ERR(0, 1877, __pyx_L1_error)
   }
   __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1876
+  /* "pywrapfst.pyx":1878
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -21318,7 +21319,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1877
+    /* "pywrapfst.pyx":1879
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -21327,12 +21328,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1877, __pyx_L1_error)
+      __PYX_ERR(0, 1879, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1877, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1879, __pyx_L1_error)
     __pyx_v__isymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1876
+    /* "pywrapfst.pyx":1878
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -21341,7 +21342,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   }
 
-  /* "pywrapfst.pyx":1878
+  /* "pywrapfst.pyx":1880
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -21350,11 +21351,11 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1878, __pyx_L1_error)
+    __PYX_ERR(0, 1880, __pyx_L1_error)
   }
   __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1879
+  /* "pywrapfst.pyx":1881
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -21365,7 +21366,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_10 = (__pyx_t_11 != 0);
   if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":1880
+    /* "pywrapfst.pyx":1882
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -21374,12 +21375,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1880, __pyx_L1_error)
+      __PYX_ERR(0, 1882, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1880, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1882, __pyx_L1_error)
     __pyx_v__osymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1879
+    /* "pywrapfst.pyx":1881
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -21388,7 +21389,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   }
 
-  /* "pywrapfst.pyx":1881
+  /* "pywrapfst.pyx":1883
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -21397,7 +21398,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   __pyx_v__ssymbols = NULL;
 
-  /* "pywrapfst.pyx":1882
+  /* "pywrapfst.pyx":1884
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -21408,7 +21409,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1883
+    /* "pywrapfst.pyx":1885
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -21417,12 +21418,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1883, __pyx_L1_error)
+      __PYX_ERR(0, 1885, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1883, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1885, __pyx_L1_error)
     __pyx_v__ssymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1882
+    /* "pywrapfst.pyx":1884
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -21431,7 +21432,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   }
 
-  /* "pywrapfst.pyx":1885
+  /* "pywrapfst.pyx":1887
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     cdef stringstream _sstrm
  *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -21440,19 +21441,19 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1885, __pyx_L1_error)
+    __PYX_ERR(0, 1887, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1893
+  /* "pywrapfst.pyx":1895
  *               acceptor,
  *               show_weight_one,
  *               tostring(missing_sym))             # <<<<<<<<<<<<<<
  *     return _sstrm.str()
  * 
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1893, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1895, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1885
+  /* "pywrapfst.pyx":1887
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     cdef stringstream _sstrm
  *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -21461,7 +21462,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   fst::script::Print((*__pyx_v_self->_fst), __pyx_v__sstrm, __pyx_k_pywrapfst, __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_9);
 
-  /* "pywrapfst.pyx":1894
+  /* "pywrapfst.pyx":1896
  *               show_weight_one,
  *               tostring(missing_sym))
  *     return _sstrm.str()             # <<<<<<<<<<<<<<
@@ -21471,7 +21472,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_r = __pyx_v__sstrm.str();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1849
+  /* "pywrapfst.pyx":1851
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -21516,7 +21517,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
     PyObject* values[6] = {0,0,0,0,0,0};
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1850
+    /* "pywrapfst.pyx":1852
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,
  *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
@@ -21584,7 +21585,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "print") < 0)) __PYX_ERR(0, 1849, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "print") < 0)) __PYX_ERR(0, 1851, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -21608,10 +21609,10 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[2]);
     if (values[3]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1851, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1853, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1851
+      /* "pywrapfst.pyx":1853
  *   cpdef string print(self, SymbolTableView isymbols=None,
  *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,             # <<<<<<<<<<<<<<
@@ -21621,7 +21622,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
       __pyx_v_acceptor = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1851, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1853, __pyx_L3_error)
     } else {
       __pyx_v_show_weight_one = ((bool)0);
     }
@@ -21629,18 +21630,18 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("print", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1849, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("print", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1851, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.print", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1849, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1850, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1850, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1851, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1852, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1852, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_3Fst_32print(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_v_missing_sym);
 
-  /* "pywrapfst.pyx":1849
+  /* "pywrapfst.pyx":1851
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
  *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
@@ -21675,8 +21676,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fs
   __pyx_t_2.acceptor = __pyx_v_acceptor;
   __pyx_t_2.show_weight_one = __pyx_v_show_weight_one;
   __pyx_t_2.missing_sym = __pyx_v_missing_sym;
-  __pyx_t_1 = __pyx_vtabptr_9pywrapfst_Fst->print(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1849, __pyx_L1_error)
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1849, __pyx_L1_error)
+  __pyx_t_1 = __pyx_vtabptr_9pywrapfst_Fst->print(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1851, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1851, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -21693,7 +21694,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1896
+/* "pywrapfst.pyx":1898
  *     return _sstrm.str()
  * 
  *   def properties(self, mask, bool test):             # <<<<<<<<<<<<<<
@@ -21736,11 +21737,11 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1896, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1898, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1896, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1898, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -21749,11 +21750,11 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, P
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_mask = values[0];
-    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1896, __pyx_L3_error)
+    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1898, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1896, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1898, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -21779,7 +21780,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
 
-  /* "pywrapfst.pyx":1914
+  /* "pywrapfst.pyx":1916
  *       A FstProperties representing a 64-bit bitmask of the requested properties.
  *     """
  *     return FstProperties(self._fst.get().Properties(mask.value, test))             # <<<<<<<<<<<<<<
@@ -21787,17 +21788,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1914, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1914, __pyx_L1_error)
+    __PYX_ERR(0, 1916, __pyx_L1_error)
   }
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1914, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyInt_As_uint64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1914, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_As_uint64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1916, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_self->_fst.get()->Properties(__pyx_t_4, __pyx_v_test)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1914, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_self->_fst.get()->Properties(__pyx_t_4, __pyx_v_test)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_5 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -21812,14 +21813,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
   __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1914, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1896
+  /* "pywrapfst.pyx":1898
  *     return _sstrm.str()
  * 
  *   def properties(self, mask, bool test):             # <<<<<<<<<<<<<<
@@ -21841,7 +21842,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1917
+/* "pywrapfst.pyx":1919
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -21872,7 +21873,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1932
+  /* "pywrapfst.pyx":1934
  *       FstIOError: Read failed.
  *     """
  *     return _read_Fst(source)             # <<<<<<<<<<<<<<
@@ -21880,13 +21881,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1932, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1934, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1917
+  /* "pywrapfst.pyx":1919
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -21905,7 +21906,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1935
+/* "pywrapfst.pyx":1937
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
@@ -21937,7 +21938,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":1950
+  /* "pywrapfst.pyx":1952
  *       FstIOError: Read failed.
  *     """
  *     return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
@@ -21945,14 +21946,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
  *   cpdef int64 start(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1950, __pyx_L1_error)
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1950, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1952, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1952, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1935
+  /* "pywrapfst.pyx":1937
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
@@ -21971,7 +21972,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1952
+/* "pywrapfst.pyx":1954
  *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -22001,7 +22002,7 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1952, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1954, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_41start)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -22017,10 +22018,10 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1952, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1954, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1952, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1954, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22039,21 +22040,21 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1958
+  /* "pywrapfst.pyx":1960
  *     Returns the start state.
  *     """
  *     return self._fst.get().Start()             # <<<<<<<<<<<<<<
  * 
- *   cpdef StateIterator states(self):
+ *   cpdef _StateIterator states(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1958, __pyx_L1_error)
+    __PYX_ERR(0, 1960, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Start();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1952
+  /* "pywrapfst.pyx":1954
  *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -22097,7 +22098,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("start", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_3Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1952, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_3Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1954, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22114,17 +22115,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1960
+/* "pywrapfst.pyx":1962
  *     return self._fst.get().Start()
  * 
- *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
+ *   cpdef _StateIterator states(self):             # <<<<<<<<<<<<<<
  *     """
  *     states(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst_StateIterator *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst__StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst__StateIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -22143,7 +22144,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1960, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1962, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_43states)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -22160,11 +22161,11 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1960, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1962, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1960, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__StateIterator))))) __PYX_ERR(0, 1962, __pyx_L1_error)
+        __pyx_r = ((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         goto __pyx_L0;
@@ -22182,24 +22183,24 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
     #endif
   }
 
-  /* "pywrapfst.pyx":1969
- *       A StateIterator object for the FST.
+  /* "pywrapfst.pyx":1971
+ *       A _StateIterator object for the FST.
  *     """
- *     return StateIterator(self)             # <<<<<<<<<<<<<<
+ *     return _StateIterator(self)             # <<<<<<<<<<<<<<
  * 
  *   cpdef bool verify(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1969, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst__StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1971, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1960
+  /* "pywrapfst.pyx":1962
  *     return self._fst.get().Start()
  * 
- *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
+ *   cpdef _StateIterator states(self):             # <<<<<<<<<<<<<<
  *     """
  *     states(self)
  */
@@ -22220,7 +22221,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_42states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A StateIterator object for the FST.\n    ";
+static char __pyx_doc_9pywrapfst_3Fst_42states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A _StateIterator object for the FST.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -22241,7 +22242,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_F
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1960, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1962, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22258,8 +22259,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1971
- *     return StateIterator(self)
+/* "pywrapfst.pyx":1973
+ *     return _StateIterator(self)
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
  *     """
@@ -22288,7 +22289,7 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1971, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1973, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_45verify)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -22304,10 +22305,10 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1971, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1973, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1971, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1973, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22326,7 +22327,7 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1980
+  /* "pywrapfst.pyx":1982
  *       True if the contents are sane, False otherwise.
  *     """
  *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
@@ -22335,13 +22336,13 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1980, __pyx_L1_error)
+    __PYX_ERR(0, 1982, __pyx_L1_error)
   }
   __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1971
- *     return StateIterator(self)
+  /* "pywrapfst.pyx":1973
+ *     return _StateIterator(self)
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
  *     """
@@ -22384,7 +22385,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_44verify(struct __pyx_obj_9pywrapfst_F
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("verify", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_3Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1971, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_3Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1973, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22401,7 +22402,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_44verify(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1982
+/* "pywrapfst.pyx":1984
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -22431,7 +22432,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1982, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1984, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_47weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -22447,10 +22448,10 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1982, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1984, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1982, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1984, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22469,7 +22470,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":1991
+  /* "pywrapfst.pyx":1993
  *       A string representing the weight type.
  *     """
  *     return self._fst.get().WeightType()             # <<<<<<<<<<<<<<
@@ -22478,12 +22479,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1991, __pyx_L1_error)
+    __PYX_ERR(0, 1993, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1982
+  /* "pywrapfst.pyx":1984
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -22527,7 +22528,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_46weight_type(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1982, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1984, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22544,7 +22545,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_46weight_type(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1993
+/* "pywrapfst.pyx":1995
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22574,7 +22575,7 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1993, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1995, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_49write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -22590,7 +22591,7 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1993, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1995, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -22610,7 +22611,7 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
     #endif
   }
 
-  /* "pywrapfst.pyx":2007
+  /* "pywrapfst.pyx":2009
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -22619,24 +22620,24 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2007, __pyx_L1_error)
+    __PYX_ERR(0, 2009, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2007, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2009, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":2008
+    /* "pywrapfst.pyx":2010
  *     """
  *     if not self._fst.get().Write(path_tostring(source)):
  *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2008, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2010, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2008, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2010, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2008, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2010, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -22652,14 +22653,14 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2008, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2010, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 2008, __pyx_L1_error)
+    __PYX_ERR(0, 2010, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2007
+    /* "pywrapfst.pyx":2009
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
@@ -22668,7 +22669,7 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   }
 
-  /* "pywrapfst.pyx":1993
+  /* "pywrapfst.pyx":1995
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22711,8 +22712,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_48write(struct __pyx_obj_9pywrapfst_Fs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_3Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1993, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1993, __pyx_L1_error)
+  __pyx_f_9pywrapfst_3Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1995, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1995, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22729,7 +22730,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_48write(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2010
+/* "pywrapfst.pyx":2012
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -22760,7 +22761,7 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2010, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2012, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_51write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
@@ -22777,10 +22778,10 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2010, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2012, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 2010, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 2012, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22799,7 +22800,7 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":2023
+  /* "pywrapfst.pyx":2025
  *     """
  *     cdef stringstream _sstrm
  *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -22808,19 +22809,19 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2023, __pyx_L1_error)
+    __PYX_ERR(0, 2025, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_v__sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":2024
+    /* "pywrapfst.pyx":2026
  *     cdef stringstream _sstrm
  *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2024, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2026, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -22834,14 +22835,14 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2024, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2026, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 2024, __pyx_L1_error)
+    __PYX_ERR(0, 2026, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2023
+    /* "pywrapfst.pyx":2025
  *     """
  *     cdef stringstream _sstrm
  *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -22850,7 +22851,7 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
  */
   }
 
-  /* "pywrapfst.pyx":2025
+  /* "pywrapfst.pyx":2027
  *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")
  *     return _sstrm.str()             # <<<<<<<<<<<<<<
@@ -22858,13 +22859,13 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2025, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2027, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2010
+  /* "pywrapfst.pyx":2012
  *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -22909,7 +22910,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_50write_to_string(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2010, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22926,7 +22927,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_50write_to_string(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2038
+/* "pywrapfst.pyx":2040
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -22945,7 +22946,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_check_mutating_imethod", 0);
 
-  /* "pywrapfst.pyx":2043
+  /* "pywrapfst.pyx":2045
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -22954,19 +22955,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2043, __pyx_L1_error)
+    __PYX_ERR(0, 2045, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->__pyx_base._fst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2044
+    /* "pywrapfst.pyx":2046
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2044, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22980,14 +22981,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2044, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2046, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2044, __pyx_L1_error)
+    __PYX_ERR(0, 2046, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2043
+    /* "pywrapfst.pyx":2045
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -22996,7 +22997,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":2038
+  /* "pywrapfst.pyx":2040
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -23015,7 +23016,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2045
+/* "pywrapfst.pyx":2047
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -23034,7 +23035,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_add_arc", 0);
 
-  /* "pywrapfst.pyx":2046
+  /* "pywrapfst.pyx":2048
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -23043,19 +23044,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2046, __pyx_L1_error)
+    __PYX_ERR(0, 2048, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2047
+    /* "pywrapfst.pyx":2049
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2047, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2049, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -23069,14 +23070,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2047, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2049, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2047, __pyx_L1_error)
+    __PYX_ERR(0, 2049, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2046
+    /* "pywrapfst.pyx":2048
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -23085,7 +23086,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2048
+  /* "pywrapfst.pyx":2050
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -23094,23 +23095,23 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2048, __pyx_L1_error)
+    __PYX_ERR(0, 2050, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2048, __pyx_L1_error)
+    __PYX_ERR(0, 2050, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->AddArc(__pyx_v_state, (*__pyx_v_arc->_arc)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2049
+    /* "pywrapfst.pyx":2051
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")             # <<<<<<<<<<<<<<
  * 
  *   def add_arc(self, int64 state, Arc arc):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2049, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2051, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -23124,14 +23125,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight_t) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight_t);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2049, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2051, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2049, __pyx_L1_error)
+    __PYX_ERR(0, 2051, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2048
+    /* "pywrapfst.pyx":2050
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -23140,7 +23141,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2045
+  /* "pywrapfst.pyx":2047
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -23159,7 +23160,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2051
+/* "pywrapfst.pyx":2053
  *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -23202,11 +23203,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_sel
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_arc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 2051, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 2053, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 2051, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 2053, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -23214,18 +23215,18 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_sel
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2051, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2053, __pyx_L3_error)
     __pyx_v_arc = ((struct __pyx_obj_9pywrapfst_Arc *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2051, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2053, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 2051, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 2053, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_add_arc(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_arc);
 
   /* function exit code */
@@ -23245,7 +23246,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_arc", 0);
 
-  /* "pywrapfst.pyx":2068
+  /* "pywrapfst.pyx":2070
  *       FstOpdexError: Incompatible or invalid weight type.
  *     """
  *     self._add_arc(state, arc)             # <<<<<<<<<<<<<<
@@ -23254,11 +23255,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_add_arc");
-    __PYX_ERR(0, 2068, __pyx_L1_error)
+    __PYX_ERR(0, 2070, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2068, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2070, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2069
+  /* "pywrapfst.pyx":2071
  *     """
  *     self._add_arc(state, arc)
  *     return self             # <<<<<<<<<<<<<<
@@ -23270,7 +23271,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2051
+  /* "pywrapfst.pyx":2053
  *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -23288,7 +23289,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2071
+/* "pywrapfst.pyx":2073
  *     return self
  * 
  *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
@@ -23318,7 +23319,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2071, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2073, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_3add_state)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -23334,10 +23335,10 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2071, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2073, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2071, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2073, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -23356,7 +23357,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":2080
+  /* "pywrapfst.pyx":2082
  *       The integer index of the new state.
  *     """
  *     return self._mfst.get().AddState()             # <<<<<<<<<<<<<<
@@ -23365,12 +23366,12 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2080, __pyx_L1_error)
+    __PYX_ERR(0, 2082, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->AddState();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2071
+  /* "pywrapfst.pyx":2073
  *     return self
  * 
  *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
@@ -23414,7 +23415,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_state", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_add_state(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2071, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_add_state(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2073, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23431,7 +23432,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2082
+/* "pywrapfst.pyx":2084
  *     return self._mfst.get().AddState()
  * 
  *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
@@ -23460,10 +23461,10 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2082, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2084, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_5add_states)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2082, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2084, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -23479,7 +23480,7 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2082, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2084, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -23499,7 +23500,7 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":2091
+  /* "pywrapfst.pyx":2093
  *       n: The number of states to add.
  *     """
  *     self._mfst.get().AddStates(n)             # <<<<<<<<<<<<<<
@@ -23508,11 +23509,11 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2091, __pyx_L1_error)
+    __PYX_ERR(0, 2093, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->AddStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2082
+  /* "pywrapfst.pyx":2084
  *     return self._mfst.get().AddState()
  * 
  *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
@@ -23545,7 +23546,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_5add_states(PyObject *__pyx_v_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2082, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2084, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -23569,7 +23570,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_10MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2082, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_10MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2084, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23586,7 +23587,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2093
+/* "pywrapfst.pyx":2095
  *     self._mfst.get().AddStates(n)
  * 
  *   cdef void _arcsort(self, sort_type="ilabel") except *:             # <<<<<<<<<<<<<<
@@ -23596,7 +23597,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9
 
 static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort *__pyx_optional_args) {
   PyObject *__pyx_v_sort_type = ((PyObject *)__pyx_n_u_ilabel);
-  enum fst::script::ArcSortType __pyx_v__sort_type;
+  fst::script::ArcSortType __pyx_v__sort_type;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -23614,29 +23615,29 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
     }
   }
 
-  /* "pywrapfst.pyx":2095
+  /* "pywrapfst.pyx":2097
  *   cdef void _arcsort(self, sort_type="ilabel") except *:
  *     cdef fst.ArcSortType _sort_type
  *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):             # <<<<<<<<<<<<<<
  *       raise FstArgError(f"Unknown sort type: {sort_type!r}")
  *     fst.ArcSort(self._mfst.get(), _sort_type)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2095, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2097, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v__sort_type)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2096
+    /* "pywrapfst.pyx":2098
  *     cdef fst.ArcSortType _sort_type
  *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
  *       raise FstArgError(f"Unknown sort type: {sort_type!r}")             # <<<<<<<<<<<<<<
  *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2096, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2098, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sort_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2096, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sort_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2098, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_sort_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2096, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_sort_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2098, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -23652,14 +23653,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2096, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2098, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2096, __pyx_L1_error)
+    __PYX_ERR(0, 2098, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2095
+    /* "pywrapfst.pyx":2097
  *   cdef void _arcsort(self, sort_type="ilabel") except *:
  *     cdef fst.ArcSortType _sort_type
  *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):             # <<<<<<<<<<<<<<
@@ -23668,7 +23669,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2097
+  /* "pywrapfst.pyx":2099
  *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
  *       raise FstArgError(f"Unknown sort type: {sort_type!r}")
  *     fst.ArcSort(self._mfst.get(), _sort_type)             # <<<<<<<<<<<<<<
@@ -23677,11 +23678,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2097, __pyx_L1_error)
+    __PYX_ERR(0, 2099, __pyx_L1_error)
   }
   fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v__sort_type);
 
-  /* "pywrapfst.pyx":2093
+  /* "pywrapfst.pyx":2095
  *     self._mfst.get().AddStates(n)
  * 
  *   cdef void _arcsort(self, sort_type="ilabel") except *:             # <<<<<<<<<<<<<<
@@ -23701,7 +23702,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2099
+/* "pywrapfst.pyx":2101
  *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
  *   def arcsort(self, sort_type="ilabel"):             # <<<<<<<<<<<<<<
@@ -23742,7 +23743,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 2099, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 2101, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23756,7 +23757,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_sel
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2099, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2101, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23778,7 +23779,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":2118
+  /* "pywrapfst.pyx":2120
  *       FstArgError: Unknown sort type.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -23787,13 +23788,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arcsort");
-    __PYX_ERR(0, 2118, __pyx_L1_error)
+    __PYX_ERR(0, 2120, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.sort_type = __pyx_v_sort_type;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_arcsort(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2118, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_arcsort(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2120, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2119
+  /* "pywrapfst.pyx":2121
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -23805,7 +23806,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2099
+  /* "pywrapfst.pyx":2101
  *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
  *   def arcsort(self, sort_type="ilabel"):             # <<<<<<<<<<<<<<
@@ -23823,7 +23824,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2121
+/* "pywrapfst.pyx":2123
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23844,7 +23845,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
     }
   }
 
-  /* "pywrapfst.pyx":2122
+  /* "pywrapfst.pyx":2124
  * 
  *   cdef void _closure(self, bool closure_plus=False):
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
@@ -23853,11 +23854,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2122, __pyx_L1_error)
+    __PYX_ERR(0, 2124, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":2121
+  /* "pywrapfst.pyx":2123
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23873,7 +23874,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2124
+/* "pywrapfst.pyx":2126
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23913,7 +23914,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 2124, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 2126, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23924,14 +23925,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_sel
       }
     }
     if (values[0]) {
-      __pyx_v_closure_plus = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_closure_plus == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2124, __pyx_L3_error)
+      __pyx_v_closure_plus = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_closure_plus == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2126, __pyx_L3_error)
     } else {
       __pyx_v_closure_plus = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2124, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2126, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23953,7 +23954,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":2142
+  /* "pywrapfst.pyx":2144
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -23962,13 +23963,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_closure");
-    __PYX_ERR(0, 2142, __pyx_L1_error)
+    __PYX_ERR(0, 2144, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.closure_plus = __pyx_v_closure_plus;
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_closure(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2143
+  /* "pywrapfst.pyx":2145
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
@@ -23980,7 +23981,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2124
+  /* "pywrapfst.pyx":2126
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23998,7 +23999,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2145
+/* "pywrapfst.pyx":2147
  *     return self
  * 
  *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
@@ -24013,7 +24014,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":2146
+  /* "pywrapfst.pyx":2148
  * 
  *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))             # <<<<<<<<<<<<<<
@@ -24022,15 +24023,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2146, __pyx_L1_error)
+    __PYX_ERR(0, 2148, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2146, __pyx_L1_error)
+    __PYX_ERR(0, 2148, __pyx_L1_error)
   }
   fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_fst2->_fst));
 
-  /* "pywrapfst.pyx":2147
+  /* "pywrapfst.pyx":2149
  *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24039,11 +24040,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2147, __pyx_L1_error)
+    __PYX_ERR(0, 2149, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2147, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2149, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2145
+  /* "pywrapfst.pyx":2147
  *     return self
  * 
  *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
@@ -24059,7 +24060,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2149
+/* "pywrapfst.pyx":2151
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
@@ -24077,7 +24078,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_11concat(PyObject *__pyx_v_sel
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst_Fst, 1, "fst2", 0))) __PYX_ERR(0, 2149, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst_Fst, 1, "fst2", 0))) __PYX_ERR(0, 2151, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_10concat(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_fst2));
 
   /* function exit code */
@@ -24097,7 +24098,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":2166
+  /* "pywrapfst.pyx":2168
  *       self.
  *     """
  *     self._concat(fst2)             # <<<<<<<<<<<<<<
@@ -24106,11 +24107,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_concat");
-    __PYX_ERR(0, 2166, __pyx_L1_error)
+    __PYX_ERR(0, 2168, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_fst2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2166, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_fst2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2168, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2167
+  /* "pywrapfst.pyx":2169
  *     """
  *     self._concat(fst2)
  *     return self             # <<<<<<<<<<<<<<
@@ -24122,7 +24123,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2149
+  /* "pywrapfst.pyx":2151
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
@@ -24140,7 +24141,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2169
+/* "pywrapfst.pyx":2171
  *     return self
  * 
  *   cdef void _connect(self):             # <<<<<<<<<<<<<<
@@ -24155,7 +24156,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":2170
+  /* "pywrapfst.pyx":2172
  * 
  *   cdef void _connect(self):
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -24164,11 +24165,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2170, __pyx_L1_error)
+    __PYX_ERR(0, 2172, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2169
+  /* "pywrapfst.pyx":2171
  *     return self
  * 
  *   cdef void _connect(self):             # <<<<<<<<<<<<<<
@@ -24184,7 +24185,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2172
+/* "pywrapfst.pyx":2174
  *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -24214,7 +24215,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":2184
+  /* "pywrapfst.pyx":2186
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -24223,11 +24224,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_connect");
-    __PYX_ERR(0, 2184, __pyx_L1_error)
+    __PYX_ERR(0, 2186, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2185
+  /* "pywrapfst.pyx":2187
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
@@ -24239,7 +24240,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2172
+  /* "pywrapfst.pyx":2174
  *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -24257,7 +24258,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2187
+/* "pywrapfst.pyx":2189
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24272,7 +24273,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":2188
+  /* "pywrapfst.pyx":2190
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))             # <<<<<<<<<<<<<<
@@ -24281,15 +24282,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2188, __pyx_L1_error)
+    __PYX_ERR(0, 2190, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 2188, __pyx_L1_error)
+    __PYX_ERR(0, 2190, __pyx_L1_error)
   }
   fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_mapper->_mapper));
 
-  /* "pywrapfst.pyx":2189
+  /* "pywrapfst.pyx":2191
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24298,11 +24299,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2189, __pyx_L1_error)
+    __PYX_ERR(0, 2191, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2189, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2191, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2187
+  /* "pywrapfst.pyx":2189
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24318,7 +24319,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2191
+/* "pywrapfst.pyx":2193
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24336,7 +24337,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_15decode(PyObject *__pyx_v_sel
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2191, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2193, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_14decode(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
@@ -24356,7 +24357,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":2205
+  /* "pywrapfst.pyx":2207
  *       self.
  *     """
  *     self._decode(mapper)             # <<<<<<<<<<<<<<
@@ -24365,11 +24366,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_decode");
-    __PYX_ERR(0, 2205, __pyx_L1_error)
+    __PYX_ERR(0, 2207, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2205, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2207, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2206
+  /* "pywrapfst.pyx":2208
  *     """
  *     self._decode(mapper)
  *     return self             # <<<<<<<<<<<<<<
@@ -24381,7 +24382,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2191
+  /* "pywrapfst.pyx":2193
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24399,7 +24400,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2208
+/* "pywrapfst.pyx":2210
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -24425,7 +24426,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
     }
   }
 
-  /* "pywrapfst.pyx":2209
+  /* "pywrapfst.pyx":2211
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24435,12 +24436,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   if ((__pyx_v_n != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2209, __pyx_L1_error)
+      __PYX_ERR(0, 2211, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":2210
+    /* "pywrapfst.pyx":2212
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else
  *             self._mfst.get().DeleteArcs(state)):             # <<<<<<<<<<<<<<
@@ -24449,12 +24450,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2210, __pyx_L1_error)
+      __PYX_ERR(0, 2212, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":2209
+  /* "pywrapfst.pyx":2211
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24464,14 +24465,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2211
+    /* "pywrapfst.pyx":2213
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2211, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2213, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24485,14 +24486,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2211, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2213, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2211, __pyx_L1_error)
+    __PYX_ERR(0, 2213, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2209
+    /* "pywrapfst.pyx":2211
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24501,7 +24502,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
   }
 
-  /* "pywrapfst.pyx":2212
+  /* "pywrapfst.pyx":2214
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24510,11 +24511,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2212, __pyx_L1_error)
+    __PYX_ERR(0, 2214, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2212, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2214, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2208
+  /* "pywrapfst.pyx":2210
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -24533,7 +24534,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2214
+/* "pywrapfst.pyx":2216
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24580,7 +24581,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2214, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2216, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24591,16 +24592,16 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2214, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2216, __pyx_L3_error)
     if (values[1]) {
-      __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2214, __pyx_L3_error)
+      __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2216, __pyx_L3_error)
     } else {
       __pyx_v_n = ((size_t)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2214, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2216, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24622,7 +24623,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":2232
+  /* "pywrapfst.pyx":2234
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -24631,13 +24632,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_arcs");
-    __PYX_ERR(0, 2232, __pyx_L1_error)
+    __PYX_ERR(0, 2234, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.n = __pyx_v_n;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_arcs(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2232, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_arcs(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2234, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2233
+  /* "pywrapfst.pyx":2235
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -24649,7 +24650,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2214
+  /* "pywrapfst.pyx":2216
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24667,7 +24668,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2235
+/* "pywrapfst.pyx":2237
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24693,17 +24694,17 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
     }
   }
 
-  /* "pywrapfst.pyx":2237
+  /* "pywrapfst.pyx":2239
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):
  *         raise FstIndexError("State index out of range")
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2237, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2239, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2238
+    /* "pywrapfst.pyx":2240
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24712,20 +24713,20 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2238, __pyx_L1_error)
+      __PYX_ERR(0, 2240, __pyx_L1_error)
     }
-    __pyx_t_2 = __pyx_convert_vector_from_py_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2238, __pyx_L1_error)
+    __pyx_t_2 = __pyx_convert_vector_from_py_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2240, __pyx_L1_error)
     __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<int64>  const )__pyx_t_2)) != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":2239
+      /* "pywrapfst.pyx":2241
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):
  *         raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     else:
  *       self._mfst.get().DeleteStates()
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2239, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2241, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_5 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24739,14 +24740,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
       }
       __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2239, __pyx_L1_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2241, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_Raise(__pyx_t_3, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __PYX_ERR(0, 2239, __pyx_L1_error)
+      __PYX_ERR(0, 2241, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":2238
+      /* "pywrapfst.pyx":2240
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24755,7 +24756,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
     }
 
-    /* "pywrapfst.pyx":2237
+    /* "pywrapfst.pyx":2239
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -24765,7 +24766,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":2241
+  /* "pywrapfst.pyx":2243
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -24775,13 +24776,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2241, __pyx_L1_error)
+      __PYX_ERR(0, 2243, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":2242
+  /* "pywrapfst.pyx":2244
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24790,11 +24791,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2242, __pyx_L1_error)
+    __PYX_ERR(0, 2244, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2242, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2244, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2235
+  /* "pywrapfst.pyx":2237
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24813,7 +24814,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2244
+/* "pywrapfst.pyx":2246
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24854,7 +24855,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2244, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2246, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24868,7 +24869,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2244, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2246, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24890,7 +24891,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":2260
+  /* "pywrapfst.pyx":2262
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
@@ -24899,13 +24900,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_states");
-    __PYX_ERR(0, 2260, __pyx_L1_error)
+    __PYX_ERR(0, 2262, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.states = __pyx_v_states;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_states(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2260, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_states(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2262, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2261
+  /* "pywrapfst.pyx":2263
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
@@ -24917,7 +24918,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2244
+  /* "pywrapfst.pyx":2246
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24935,7 +24936,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2263
+/* "pywrapfst.pyx":2265
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24950,7 +24951,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":2264
+  /* "pywrapfst.pyx":2266
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())             # <<<<<<<<<<<<<<
@@ -24959,15 +24960,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2264, __pyx_L1_error)
+    __PYX_ERR(0, 2266, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 2264, __pyx_L1_error)
+    __PYX_ERR(0, 2266, __pyx_L1_error)
   }
   fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_mapper->_mapper.get());
 
-  /* "pywrapfst.pyx":2265
+  /* "pywrapfst.pyx":2267
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24976,11 +24977,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2265, __pyx_L1_error)
+    __PYX_ERR(0, 2267, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2265, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2267, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2263
+  /* "pywrapfst.pyx":2265
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24996,7 +24997,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2267
+/* "pywrapfst.pyx":2269
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -25014,7 +25015,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_21encode(PyObject *__pyx_v_sel
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2267, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2269, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_20encode(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
@@ -25034,7 +25035,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":2286
+  /* "pywrapfst.pyx":2288
  *       self.
  *     """
  *     self._encode(mapper)             # <<<<<<<<<<<<<<
@@ -25043,11 +25044,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encode");
-    __PYX_ERR(0, 2286, __pyx_L1_error)
+    __PYX_ERR(0, 2288, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2286, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2288, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2287
+  /* "pywrapfst.pyx":2289
  *     """
  *     self._encode(mapper)
  *     return self             # <<<<<<<<<<<<<<
@@ -25059,7 +25060,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2267
+  /* "pywrapfst.pyx":2269
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -25077,7 +25078,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2289
+/* "pywrapfst.pyx":2291
  *     return self
  * 
  *   cdef void _invert(self):             # <<<<<<<<<<<<<<
@@ -25092,7 +25093,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":2290
+  /* "pywrapfst.pyx":2292
  * 
  *   cdef void _invert(self):
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -25101,11 +25102,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2290, __pyx_L1_error)
+    __PYX_ERR(0, 2292, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2289
+  /* "pywrapfst.pyx":2291
  *     return self
  * 
  *   cdef void _invert(self):             # <<<<<<<<<<<<<<
@@ -25121,7 +25122,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2292
+/* "pywrapfst.pyx":2294
  *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -25151,7 +25152,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2304
+  /* "pywrapfst.pyx":2306
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -25160,11 +25161,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_invert");
-    __PYX_ERR(0, 2304, __pyx_L1_error)
+    __PYX_ERR(0, 2306, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2305
+  /* "pywrapfst.pyx":2307
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
@@ -25176,7 +25177,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2292
+  /* "pywrapfst.pyx":2294
  *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -25194,7 +25195,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2307
+/* "pywrapfst.pyx":2309
  *     return self
  * 
  *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
@@ -25205,7 +25206,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
 static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args) {
   float __pyx_v_delta = __pyx_k__12;
 
-  /* "pywrapfst.pyx":2309
+  /* "pywrapfst.pyx":2311
  *   cdef void _minimize(self,
  *                       float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
@@ -25227,7 +25228,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2311
+  /* "pywrapfst.pyx":2313
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -25236,11 +25237,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2311, __pyx_L1_error)
+    __PYX_ERR(0, 2313, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2312
+  /* "pywrapfst.pyx":2314
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25249,11 +25250,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2312, __pyx_L1_error)
+    __PYX_ERR(0, 2314, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2312, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2314, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2307
+  /* "pywrapfst.pyx":2309
  *     return self
  * 
  *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
@@ -25269,7 +25270,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2314
+/* "pywrapfst.pyx":2316
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -25318,7 +25319,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2314, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2316, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25331,19 +25332,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_s
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2314, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2316, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__13;
     }
     if (values[1]) {
-      __pyx_v_allow_nondet = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_nondet == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2314, __pyx_L3_error)
+      __pyx_v_allow_nondet = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_nondet == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2316, __pyx_L3_error)
     } else {
       __pyx_v_allow_nondet = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2314, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2316, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -25365,7 +25366,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2340
+  /* "pywrapfst.pyx":2342
  *       self.
  *     """
  *     self._minimize(delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -25374,26 +25375,26 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_minimize");
-    __PYX_ERR(0, 2340, __pyx_L1_error)
+    __PYX_ERR(0, 2342, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 2;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.allow_nondet = __pyx_v_allow_nondet;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_minimize(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2340, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_minimize(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2342, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2341
+  /* "pywrapfst.pyx":2343
  *     """
  *     self._minimize(delta, allow_nondet)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cpdef MutableArcIterator mutable_arcs(self, int64 state):
+ *   cpdef _MutableArcIterator mutable_arcs(self, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2314
+  /* "pywrapfst.pyx":2316
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -25411,17 +25412,17 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2343
+/* "pywrapfst.pyx":2345
  *     return self
  * 
- *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
+ *   cpdef _MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
  *     mutable_arcs(self, state)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -25441,11 +25442,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2343, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2345, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2343, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2345, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -25461,11 +25462,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2343, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2345, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2343, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__MutableArcIterator))))) __PYX_ERR(0, 2345, __pyx_L1_error)
+        __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         goto __pyx_L0;
@@ -25483,17 +25484,17 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
     #endif
   }
 
-  /* "pywrapfst.pyx":2355
- *       A MutableArcIterator.
+  /* "pywrapfst.pyx":2357
+ *       A _MutableArcIterator.
  *     """
- *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
+ *     return _MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
  * 
  *   def mutable_input_symbols(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2355, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2355, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -25501,17 +25502,17 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_MutableArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2355, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst__MutableArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2357, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2343
+  /* "pywrapfst.pyx":2345
  *     return self
  * 
- *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
+ *   cpdef _MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
  *     mutable_arcs(self, state)
  */
@@ -25533,7 +25534,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_10MutableFst_26mutable_arcs[] = "\n    mutable_arcs(self, state)\n\n    Returns a mutable iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      A MutableArcIterator.\n    ";
+static char __pyx_doc_9pywrapfst_10MutableFst_26mutable_arcs[] = "\n    mutable_arcs(self, state)\n\n    Returns a mutable iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      A _MutableArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
   int __pyx_lineno = 0;
@@ -25543,7 +25544,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2343, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2345, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -25567,7 +25568,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2343, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2345, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25584,8 +25585,8 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2357
- *     return MutableArcIterator(self, state)
+/* "pywrapfst.pyx":2359
+ *     return _MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -25616,7 +25617,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2363
+  /* "pywrapfst.pyx":2365
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
  *     if self._mfst.get().MutableInputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -25625,12 +25626,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2363, __pyx_L1_error)
+    __PYX_ERR(0, 2365, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->_mfst.get()->MutableInputSymbols() == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2364
+    /* "pywrapfst.pyx":2366
  *     """
  *     if self._mfst.get().MutableInputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -25641,7 +25642,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2363
+    /* "pywrapfst.pyx":2365
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
  *     if self._mfst.get().MutableInputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -25650,7 +25651,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
  */
   }
 
-  /* "pywrapfst.pyx":2365
+  /* "pywrapfst.pyx":2367
  *     if self._mfst.get().MutableInputSymbols() == NULL:
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)             # <<<<<<<<<<<<<<
@@ -25660,16 +25661,16 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2365, __pyx_L1_error)
+    __PYX_ERR(0, 2367, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2365, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2367, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2357
- *     return MutableArcIterator(self, state)
+  /* "pywrapfst.pyx":2359
+ *     return _MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -25687,7 +25688,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2367
+/* "pywrapfst.pyx":2369
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -25719,7 +25720,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2373
+  /* "pywrapfst.pyx":2375
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
  *     if self._mfst.get().MutableOutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -25728,12 +25729,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2373, __pyx_L1_error)
+    __PYX_ERR(0, 2375, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->_mfst.get()->MutableOutputSymbols() == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2374
+    /* "pywrapfst.pyx":2376
  *     """
  *     if self._mfst.get().MutableOutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -25744,7 +25745,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2373
+    /* "pywrapfst.pyx":2375
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
  *     if self._mfst.get().MutableOutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -25753,7 +25754,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
  */
   }
 
-  /* "pywrapfst.pyx":2375
+  /* "pywrapfst.pyx":2377
  *     if self._mfst.get().MutableOutputSymbols() == NULL:
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)             # <<<<<<<<<<<<<<
@@ -25763,15 +25764,15 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2375, __pyx_L1_error)
+    __PYX_ERR(0, 2377, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2375, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2377, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2367
+  /* "pywrapfst.pyx":2369
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -25790,7 +25791,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2377
+/* "pywrapfst.pyx":2379
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -25820,7 +25821,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2377, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2379, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_33num_states)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -25836,10 +25837,10 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2377, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2379, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2377, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2379, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -25858,7 +25859,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":2383
+  /* "pywrapfst.pyx":2385
  *     Returns the number of states.
  *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
@@ -25867,12 +25868,12 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2383, __pyx_L1_error)
+    __PYX_ERR(0, 2385, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2377
+  /* "pywrapfst.pyx":2379
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -25916,7 +25917,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2377, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2379, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25933,7 +25934,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2385
+/* "pywrapfst.pyx":2387
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, project_type) except *:             # <<<<<<<<<<<<<<
@@ -25950,7 +25951,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_project", 0);
 
-  /* "pywrapfst.pyx":2386
+  /* "pywrapfst.pyx":2388
  * 
  *   cdef void _project(self, project_type) except *:
  *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))             # <<<<<<<<<<<<<<
@@ -25959,13 +25960,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2386, __pyx_L1_error)
+    __PYX_ERR(0, 2388, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2386, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_project_type(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2386, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2388, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_project_type(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2388, __pyx_L1_error)
   fst::script::Project(__pyx_v_self->_mfst.get(), __pyx_t_2);
 
-  /* "pywrapfst.pyx":2385
+  /* "pywrapfst.pyx":2387
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, project_type) except *:             # <<<<<<<<<<<<<<
@@ -25981,7 +25982,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2388
+/* "pywrapfst.pyx":2390
  *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
  *   def project(self, project_type):             # <<<<<<<<<<<<<<
@@ -26011,7 +26012,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2405
+  /* "pywrapfst.pyx":2407
  *       self.
  *     """
  *     self._project(project_type)             # <<<<<<<<<<<<<<
@@ -26020,11 +26021,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_project");
-    __PYX_ERR(0, 2405, __pyx_L1_error)
+    __PYX_ERR(0, 2407, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, __pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2405, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, __pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2407, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2406
+  /* "pywrapfst.pyx":2408
  *     """
  *     self._project(project_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -26036,7 +26037,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2388
+  /* "pywrapfst.pyx":2390
  *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
  *   def project(self, project_type):             # <<<<<<<<<<<<<<
@@ -26054,7 +26055,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2408
+/* "pywrapfst.pyx":2410
  *     return self
  * 
  *   cdef void _prune(self,             # <<<<<<<<<<<<<<
@@ -26066,7 +26067,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
   float __pyx_v_delta = __pyx_k__14;
   int64 __pyx_v_nstate = __pyx_k__15;
 
-  /* "pywrapfst.pyx":2411
+  /* "pywrapfst.pyx":2413
  *                    float delta=fst.kDelta,
  *                    int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:             # <<<<<<<<<<<<<<
@@ -26093,7 +26094,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
     }
   }
 
-  /* "pywrapfst.pyx":2413
+  /* "pywrapfst.pyx":2415
  *                    weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26102,20 +26103,20 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2413, __pyx_L1_error)
+    __PYX_ERR(0, 2415, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2414
+  /* "pywrapfst.pyx":2416
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_zero(self.weight_type(),
  *                                                             weight)             # <<<<<<<<<<<<<<
  *     fst.Prune(self._mfst.get(), _weight, nstate, delta)
  *     self._check_mutating_imethod()
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2413, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2415, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2415
+  /* "pywrapfst.pyx":2417
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_zero(self.weight_type(),
  *                                                             weight)
  *     fst.Prune(self._mfst.get(), _weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -26124,11 +26125,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2415, __pyx_L1_error)
+    __PYX_ERR(0, 2417, __pyx_L1_error)
   }
   fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2416
+  /* "pywrapfst.pyx":2418
  *                                                             weight)
  *     fst.Prune(self._mfst.get(), _weight, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26137,11 +26138,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2416, __pyx_L1_error)
+    __PYX_ERR(0, 2418, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2416, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2418, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2408
+  /* "pywrapfst.pyx":2410
  *     return self
  * 
  *   cdef void _prune(self,             # <<<<<<<<<<<<<<
@@ -26157,7 +26158,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2418
+/* "pywrapfst.pyx":2420
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26182,7 +26183,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[3] = {0,0,0};
 
-    /* "pywrapfst.pyx":2421
+    /* "pywrapfst.pyx":2423
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -26224,7 +26225,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2418, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2420, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26239,12 +26240,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2419, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2421, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__16;
     }
     if (values[1]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2420, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2422, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__17;
     }
@@ -26252,7 +26253,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2418, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2420, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26260,7 +26261,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_36prune(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":2418
+  /* "pywrapfst.pyx":2420
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26282,7 +26283,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2441
+  /* "pywrapfst.pyx":2443
  *       self.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -26291,15 +26292,15 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_prune");
-    __PYX_ERR(0, 2441, __pyx_L1_error)
+    __PYX_ERR(0, 2443, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.weight = __pyx_v_weight;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_prune(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2441, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_prune(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2443, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2442
+  /* "pywrapfst.pyx":2444
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -26311,7 +26312,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2418
+  /* "pywrapfst.pyx":2420
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26329,7 +26330,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2444
+/* "pywrapfst.pyx":2446
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -26340,7 +26341,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
 static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__push *__pyx_optional_args) {
   float __pyx_v_delta = __pyx_k__18;
 
-  /* "pywrapfst.pyx":2446
+  /* "pywrapfst.pyx":2448
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -26349,7 +26350,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2447
+  /* "pywrapfst.pyx":2449
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
  *                   bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26374,7 +26375,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
     }
   }
 
-  /* "pywrapfst.pyx":2448
+  /* "pywrapfst.pyx":2450
  *                   bool remove_total_weight=False,
  *                   bool to_final=False):
  *     fst.Push(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -26383,10 +26384,10 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2448, __pyx_L1_error)
+    __PYX_ERR(0, 2450, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2451
+  /* "pywrapfst.pyx":2453
  *              fst.GetReweightType(to_final),
  *              delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
@@ -26395,7 +26396,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
  */
   fst::script::Push(__pyx_v_self->_mfst.get(), fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta, __pyx_v_remove_total_weight);
 
-  /* "pywrapfst.pyx":2444
+  /* "pywrapfst.pyx":2446
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -26411,7 +26412,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2453
+/* "pywrapfst.pyx":2455
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26469,7 +26470,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2453, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2455, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26484,15 +26485,15 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2454, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2456, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__19;
     }
     if (values[1]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2455, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2457, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2455
+      /* "pywrapfst.pyx":2457
  *   def push(self,
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -26502,10 +26503,10 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2456, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2458, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2456
+      /* "pywrapfst.pyx":2458
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26517,7 +26518,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2453, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2455, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26525,7 +26526,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_38push(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":2453
+  /* "pywrapfst.pyx":2455
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26547,7 +26548,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2480
+  /* "pywrapfst.pyx":2482
  *       self.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
@@ -26556,7 +26557,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_push");
-    __PYX_ERR(0, 2480, __pyx_L1_error)
+    __PYX_ERR(0, 2482, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
@@ -26564,7 +26565,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   __pyx_t_1.to_final = __pyx_v_to_final;
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_push(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2481
+  /* "pywrapfst.pyx":2483
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -26576,7 +26577,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2453
+  /* "pywrapfst.pyx":2455
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26594,7 +26595,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2483
+/* "pywrapfst.pyx":2485
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -26636,17 +26637,17 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
     }
   }
 
-  /* "pywrapfst.pyx":2486
+  /* "pywrapfst.pyx":2488
  *     cdef vector[fst.LabelPair] _ipairs
  *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in ipairs:
  *         _ipairs.push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2486, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2488, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2487
+    /* "pywrapfst.pyx":2489
  *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -26657,26 +26658,26 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
       __pyx_t_2 = __pyx_v_ipairs; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
       __pyx_t_4 = NULL;
     } else {
-      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2487, __pyx_L1_error)
+      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2489, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2487, __pyx_L1_error)
+      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2489, __pyx_L1_error)
     }
     for (;;) {
       if (likely(!__pyx_t_4)) {
         if (likely(PyList_CheckExact(__pyx_t_2))) {
           if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2487, __pyx_L1_error)
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2489, __pyx_L1_error)
           #else
-          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2487, __pyx_L1_error)
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2489, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           #endif
         } else {
           if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2487, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2489, __pyx_L1_error)
           #else
-          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2487, __pyx_L1_error)
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2489, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           #endif
         }
@@ -26686,7 +26687,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2487, __pyx_L1_error)
+            else __PYX_ERR(0, 2489, __pyx_L1_error)
           }
           break;
         }
@@ -26698,7 +26699,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2487, __pyx_L1_error)
+          __PYX_ERR(0, 2489, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -26711,15 +26712,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(__pyx_t_7);
         #else
-        __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2487, __pyx_L1_error)
+        __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2489, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
-        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2487, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2489, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         #endif
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2487, __pyx_L1_error)
+        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2489, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
@@ -26727,7 +26728,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_GOTREF(__pyx_t_6);
         index = 1; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_7);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2487, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2489, __pyx_L1_error)
         __pyx_t_9 = NULL;
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         goto __pyx_L7_unpacking_done;
@@ -26735,7 +26736,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __pyx_t_9 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2487, __pyx_L1_error)
+        __PYX_ERR(0, 2489, __pyx_L1_error)
         __pyx_L7_unpacking_done:;
       }
       __Pyx_XDECREF_SET(__pyx_v_before, __pyx_t_6);
@@ -26743,29 +26744,29 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
       __Pyx_XDECREF_SET(__pyx_v_after, __pyx_t_7);
       __pyx_t_7 = 0;
 
-      /* "pywrapfst.pyx":2488
+      /* "pywrapfst.pyx":2490
  *     if ipairs:
  *       for (before, after) in ipairs:
  *         _ipairs.push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
  *     if opairs:
  *       for (before, after) in opairs:
  */
-      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2488, __pyx_L1_error)
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2488, __pyx_L1_error)
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2490, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2490, __pyx_L1_error)
       try {
         __pyx_t_12 = __pyx_t_10cpywrapfst_LabelPair(__pyx_t_10, __pyx_t_11);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2488, __pyx_L1_error)
+        __PYX_ERR(0, 2490, __pyx_L1_error)
       }
       try {
         __pyx_v__ipairs.push_back(__pyx_t_12);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2488, __pyx_L1_error)
+        __PYX_ERR(0, 2490, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2487
+      /* "pywrapfst.pyx":2489
  *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -26775,7 +26776,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
     }
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2486
+    /* "pywrapfst.pyx":2488
  *     cdef vector[fst.LabelPair] _ipairs
  *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:             # <<<<<<<<<<<<<<
@@ -26784,17 +26785,17 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2489
+  /* "pywrapfst.pyx":2491
  *       for (before, after) in ipairs:
  *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in opairs:
  *         _opairs.push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2489, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2491, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2490
+    /* "pywrapfst.pyx":2492
  *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -26805,26 +26806,26 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
       __pyx_t_2 = __pyx_v_opairs; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
       __pyx_t_4 = NULL;
     } else {
-      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2490, __pyx_L1_error)
+      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2492, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2490, __pyx_L1_error)
+      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2492, __pyx_L1_error)
     }
     for (;;) {
       if (likely(!__pyx_t_4)) {
         if (likely(PyList_CheckExact(__pyx_t_2))) {
           if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2490, __pyx_L1_error)
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2492, __pyx_L1_error)
           #else
-          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2490, __pyx_L1_error)
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2492, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           #endif
         } else {
           if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2490, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2492, __pyx_L1_error)
           #else
-          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2490, __pyx_L1_error)
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2492, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           #endif
         }
@@ -26834,7 +26835,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2490, __pyx_L1_error)
+            else __PYX_ERR(0, 2492, __pyx_L1_error)
           }
           break;
         }
@@ -26846,7 +26847,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2490, __pyx_L1_error)
+          __PYX_ERR(0, 2492, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -26859,15 +26860,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_INCREF(__pyx_t_7);
         __Pyx_INCREF(__pyx_t_6);
         #else
-        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2490, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2492, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2490, __pyx_L1_error)
+        __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2492, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
         #endif
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2490, __pyx_L1_error)
+        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2492, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
@@ -26875,7 +26876,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_GOTREF(__pyx_t_7);
         index = 1; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_6);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2490, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2492, __pyx_L1_error)
         __pyx_t_9 = NULL;
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         goto __pyx_L12_unpacking_done;
@@ -26883,7 +26884,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         __pyx_t_9 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2490, __pyx_L1_error)
+        __PYX_ERR(0, 2492, __pyx_L1_error)
         __pyx_L12_unpacking_done:;
       }
       __Pyx_XDECREF_SET(__pyx_v_before, __pyx_t_7);
@@ -26891,29 +26892,29 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
       __Pyx_XDECREF_SET(__pyx_v_after, __pyx_t_6);
       __pyx_t_6 = 0;
 
-      /* "pywrapfst.pyx":2491
+      /* "pywrapfst.pyx":2493
  *     if opairs:
  *       for (before, after) in opairs:
  *         _opairs.push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
  *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")
  */
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2491, __pyx_L1_error)
-      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2491, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2493, __pyx_L1_error)
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2493, __pyx_L1_error)
       try {
         __pyx_t_12 = __pyx_t_10cpywrapfst_LabelPair(__pyx_t_11, __pyx_t_10);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2491, __pyx_L1_error)
+        __PYX_ERR(0, 2493, __pyx_L1_error)
       }
       try {
         __pyx_v__opairs.push_back(__pyx_t_12);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2491, __pyx_L1_error)
+        __PYX_ERR(0, 2493, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2490
+      /* "pywrapfst.pyx":2492
  *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -26923,7 +26924,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
     }
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2489
+    /* "pywrapfst.pyx":2491
  *       for (before, after) in ipairs:
  *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
@@ -26932,7 +26933,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2492
+  /* "pywrapfst.pyx":2494
  *       for (before, after) in opairs:
  *         _opairs.push_back(fst.LabelPair(before, after))
  *     if _ipairs.empty() and _opairs.empty():             # <<<<<<<<<<<<<<
@@ -26950,14 +26951,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
   __pyx_L14_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2493
+    /* "pywrapfst.pyx":2495
  *         _opairs.push_back(fst.LabelPair(before, after))
  *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2493, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2495, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -26971,14 +26972,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
     }
     __pyx_t_2 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_No_relabeling_pairs_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_No_relabeling_pairs_specified);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2493, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2495, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2493, __pyx_L1_error)
+    __PYX_ERR(0, 2495, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2492
+    /* "pywrapfst.pyx":2494
  *       for (before, after) in opairs:
  *         _opairs.push_back(fst.LabelPair(before, after))
  *     if _ipairs.empty() and _opairs.empty():             # <<<<<<<<<<<<<<
@@ -26987,7 +26988,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2494
+  /* "pywrapfst.pyx":2496
  *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)             # <<<<<<<<<<<<<<
@@ -26996,11 +26997,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2494, __pyx_L1_error)
+    __PYX_ERR(0, 2496, __pyx_L1_error)
   }
   fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_v__ipairs, __pyx_v__opairs);
 
-  /* "pywrapfst.pyx":2495
+  /* "pywrapfst.pyx":2497
  *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27009,11 +27010,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2495, __pyx_L1_error)
+    __PYX_ERR(0, 2497, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2495, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2497, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2483
+  /* "pywrapfst.pyx":2485
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -27036,7 +27037,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2497
+/* "pywrapfst.pyx":2499
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -27087,7 +27088,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2497, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2499, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27104,7 +27105,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2497, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2499, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27126,7 +27127,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2517
+  /* "pywrapfst.pyx":2519
  *       FstArgError: No relabeling pairs specified.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
@@ -27135,14 +27136,14 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_pairs");
-    __PYX_ERR(0, 2517, __pyx_L1_error)
+    __PYX_ERR(0, 2519, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 2;
   __pyx_t_1.ipairs = __pyx_v_ipairs;
   __pyx_t_1.opairs = __pyx_v_opairs;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_pairs(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2517, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_pairs(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2519, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2518
+  /* "pywrapfst.pyx":2520
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -27154,7 +27155,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2497
+  /* "pywrapfst.pyx":2499
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -27172,7 +27173,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2520
+/* "pywrapfst.pyx":2522
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27182,7 +27183,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
 
 static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":2521
+  /* "pywrapfst.pyx":2523
  * 
  *   cdef void _relabel_tables(self,
  *                             SymbolTableView old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27191,7 +27192,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":2522
+  /* "pywrapfst.pyx":2524
  *   cdef void _relabel_tables(self,
  *                             SymbolTableView old_isymbols=None,
  *                             SymbolTableView new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27201,7 +27202,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
   PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_u__11);
 
-  /* "pywrapfst.pyx":2524
+  /* "pywrapfst.pyx":2526
  *                             SymbolTableView new_isymbols=None,
  *                             unknown_isymbol="",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -27210,7 +27211,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2525
+  /* "pywrapfst.pyx":2527
  *                             unknown_isymbol="",
  *                             bool attach_new_isymbols=True,
  *                             SymbolTableView old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27219,7 +27220,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":2526
+  /* "pywrapfst.pyx":2528
  *                             bool attach_new_isymbols=True,
  *                             SymbolTableView old_osymbols=None,
  *                             SymbolTableView new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27229,7 +27230,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
   PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_u__11);
 
-  /* "pywrapfst.pyx":2528
+  /* "pywrapfst.pyx":2530
  *                             SymbolTableView new_osymbols=None,
  *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
@@ -27282,7 +27283,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2529
+  /* "pywrapfst.pyx":2531
  *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -27302,14 +27303,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_L4_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2530
+    /* "pywrapfst.pyx":2532
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2530, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2532, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -27323,14 +27324,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
     }
     __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_No_new_SymbolTables_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_No_new_SymbolTables_specified);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2530, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2532, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 2530, __pyx_L1_error)
+    __PYX_ERR(0, 2532, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2529
+    /* "pywrapfst.pyx":2531
  *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -27339,7 +27340,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2531
+  /* "pywrapfst.pyx":2533
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
@@ -27348,11 +27349,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2531, __pyx_L1_error)
+    __PYX_ERR(0, 2533, __pyx_L1_error)
   }
   __pyx_v__old_isymbols = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":2532
+  /* "pywrapfst.pyx":2534
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27363,7 +27364,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2533
+    /* "pywrapfst.pyx":2535
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27372,12 +27373,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2533, __pyx_L1_error)
+      __PYX_ERR(0, 2535, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2533, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2535, __pyx_L1_error)
     __pyx_v__old_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2532
+    /* "pywrapfst.pyx":2534
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27386,7 +27387,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2534
+  /* "pywrapfst.pyx":2536
  *     if old_isymbols is not None:
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -27395,11 +27396,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2534, __pyx_L1_error)
+    __PYX_ERR(0, 2536, __pyx_L1_error)
   }
   __pyx_v__old_osymbols = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":2535
+  /* "pywrapfst.pyx":2537
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27410,7 +27411,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2536
+    /* "pywrapfst.pyx":2538
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27419,12 +27420,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2536, __pyx_L1_error)
+      __PYX_ERR(0, 2538, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2536, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2538, __pyx_L1_error)
     __pyx_v__old_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2535
+    /* "pywrapfst.pyx":2537
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27433,7 +27434,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2537
+  /* "pywrapfst.pyx":2539
  *     if old_osymbols is not None:
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL             # <<<<<<<<<<<<<<
@@ -27442,7 +27443,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   __pyx_v__new_isymbols = NULL;
 
-  /* "pywrapfst.pyx":2538
+  /* "pywrapfst.pyx":2540
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27453,7 +27454,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2539
+    /* "pywrapfst.pyx":2541
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27462,12 +27463,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_new_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2539, __pyx_L1_error)
+      __PYX_ERR(0, 2541, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2539, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2541, __pyx_L1_error)
     __pyx_v__new_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2538
+    /* "pywrapfst.pyx":2540
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27476,7 +27477,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2540
+  /* "pywrapfst.pyx":2542
  *     if new_isymbols is not None:
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL             # <<<<<<<<<<<<<<
@@ -27485,7 +27486,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   __pyx_v__new_osymbols = NULL;
 
-  /* "pywrapfst.pyx":2541
+  /* "pywrapfst.pyx":2543
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27496,7 +27497,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2542
+    /* "pywrapfst.pyx":2544
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27505,12 +27506,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_new_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2542, __pyx_L1_error)
+      __PYX_ERR(0, 2544, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2542, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2544, __pyx_L1_error)
     __pyx_v__new_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2541
+    /* "pywrapfst.pyx":2543
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27519,7 +27520,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2543
+  /* "pywrapfst.pyx":2545
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -27528,28 +27529,28 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2543, __pyx_L1_error)
+    __PYX_ERR(0, 2545, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2546
+  /* "pywrapfst.pyx":2548
  *         _old_isymbols,
  *         _new_isymbols,
  *         tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
  *         attach_new_isymbols,
  *         _old_osymbols,
  */
-  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2546, __pyx_L1_error)
+  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2548, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2550
+  /* "pywrapfst.pyx":2552
  *         _old_osymbols,
  *         _new_osymbols,
  *         tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2550, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2552, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2543
+  /* "pywrapfst.pyx":2545
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -27558,7 +27559,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_v__old_isymbols, __pyx_v__new_isymbols, __pyx_t_8, __pyx_v_attach_new_isymbols, __pyx_v__old_osymbols, __pyx_v__new_osymbols, __pyx_t_9, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2552
+  /* "pywrapfst.pyx":2554
  *         tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27567,11 +27568,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2552, __pyx_L1_error)
+    __PYX_ERR(0, 2554, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2552, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2554, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2520
+  /* "pywrapfst.pyx":2522
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27590,7 +27591,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2554
+/* "pywrapfst.pyx":2556
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27620,7 +27621,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_old_isymbols,&__pyx_n_s_new_isymbols,&__pyx_n_s_unknown_isymbol,&__pyx_n_s_attach_new_isymbols,&__pyx_n_s_old_osymbols,&__pyx_n_s_new_osymbols,&__pyx_n_s_unknown_osymbol,&__pyx_n_s_attach_new_osymbols,0};
     PyObject* values[8] = {0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":2555
+    /* "pywrapfst.pyx":2557
  * 
  *   def relabel_tables(self,
  *                      SymbolTableView old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27629,7 +27630,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
  */
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":2556
+    /* "pywrapfst.pyx":2558
  *   def relabel_tables(self,
  *                      SymbolTableView old_isymbols=None,
  *                      SymbolTableView new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27639,7 +27640,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
     values[2] = ((PyObject *)__pyx_kp_u__11);
 
-    /* "pywrapfst.pyx":2559
+    /* "pywrapfst.pyx":2561
  *                      unknown_isymbol="",
  *                      bool attach_new_isymbols=True,
  *                      SymbolTableView old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27648,7 +27649,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
  */
     values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":2560
+    /* "pywrapfst.pyx":2562
  *                      bool attach_new_isymbols=True,
  *                      SymbolTableView old_osymbols=None,
  *                      SymbolTableView new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27731,7 +27732,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2554, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2556, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27759,10 +27760,10 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
     __pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
     __pyx_v_unknown_isymbol = values[2];
     if (values[3]) {
-      __pyx_v_attach_new_isymbols = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_attach_new_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2558, __pyx_L3_error)
+      __pyx_v_attach_new_isymbols = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_attach_new_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2560, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2558
+      /* "pywrapfst.pyx":2560
  *                      SymbolTableView new_isymbols=None,
  *                      unknown_isymbol="",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -27775,10 +27776,10 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
     __pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[5]);
     __pyx_v_unknown_osymbol = values[6];
     if (values[7]) {
-      __pyx_v_attach_new_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_attach_new_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2562, __pyx_L3_error)
+      __pyx_v_attach_new_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_attach_new_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2564, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2562
+      /* "pywrapfst.pyx":2564
  *                      SymbolTableView new_osymbols=None,
  *                      unknown_osymbol="",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
@@ -27790,19 +27791,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2554, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2556, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_isymbols", 0))) __PYX_ERR(0, 2555, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_isymbols", 0))) __PYX_ERR(0, 2556, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_osymbols", 0))) __PYX_ERR(0, 2559, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_osymbols", 0))) __PYX_ERR(0, 2560, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_isymbols", 0))) __PYX_ERR(0, 2557, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_isymbols", 0))) __PYX_ERR(0, 2558, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_osymbols", 0))) __PYX_ERR(0, 2561, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_osymbols", 0))) __PYX_ERR(0, 2562, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_old_isymbols, __pyx_v_new_isymbols, __pyx_v_unknown_isymbol, __pyx_v_attach_new_isymbols, __pyx_v_old_osymbols, __pyx_v_new_osymbols, __pyx_v_unknown_osymbol, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2554
+  /* "pywrapfst.pyx":2556
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27828,7 +27829,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2596
+  /* "pywrapfst.pyx":2598
  *       FstArgError: No SymbolTable specified.
  *     """
  *     self._relabel_tables(old_isymbols,             # <<<<<<<<<<<<<<
@@ -27837,10 +27838,10 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_tables");
-    __PYX_ERR(0, 2596, __pyx_L1_error)
+    __PYX_ERR(0, 2598, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2603
+  /* "pywrapfst.pyx":2605
  *                          new_osymbols,
  *                          unknown_osymbol,
  *                          attach_new_osymbols)             # <<<<<<<<<<<<<<
@@ -27856,9 +27857,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   __pyx_t_1.new_osymbols = __pyx_v_new_osymbols;
   __pyx_t_1.unknown_osymbol = __pyx_v_unknown_osymbol;
   __pyx_t_1.attach_new_osymbols = __pyx_v_attach_new_osymbols;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_tables(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2596, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_tables(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2598, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2604
+  /* "pywrapfst.pyx":2606
  *                          unknown_osymbol,
  *                          attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -27870,7 +27871,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2554
+  /* "pywrapfst.pyx":2556
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27888,7 +27889,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2606
+/* "pywrapfst.pyx":2608
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -27907,7 +27908,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2607
+  /* "pywrapfst.pyx":2609
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -27916,19 +27917,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2607, __pyx_L1_error)
+    __PYX_ERR(0, 2609, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ReserveArcs(__pyx_v_state, __pyx_v_n) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2608
+    /* "pywrapfst.pyx":2610
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2608, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2610, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27942,14 +27943,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2608, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2610, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2608, __pyx_L1_error)
+    __PYX_ERR(0, 2610, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2607
+    /* "pywrapfst.pyx":2609
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -27958,7 +27959,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":2609
+  /* "pywrapfst.pyx":2611
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27967,11 +27968,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2609, __pyx_L1_error)
+    __PYX_ERR(0, 2611, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2609, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2611, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2606
+  /* "pywrapfst.pyx":2608
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -27990,7 +27991,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2611
+/* "pywrapfst.pyx":2613
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -28033,11 +28034,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2611, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2613, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2611, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2613, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -28045,12 +28046,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2611, __pyx_L3_error)
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2611, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2613, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2613, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2611, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2613, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28071,7 +28072,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2627
+  /* "pywrapfst.pyx":2629
  *       FstIndexError: State index out of range.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -28080,11 +28081,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_arcs");
-    __PYX_ERR(0, 2627, __pyx_L1_error)
+    __PYX_ERR(0, 2629, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_arcs(__pyx_v_self, __pyx_v_state, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2627, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_arcs(__pyx_v_self, __pyx_v_state, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2629, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2628
+  /* "pywrapfst.pyx":2630
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -28096,7 +28097,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2611
+  /* "pywrapfst.pyx":2613
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -28114,7 +28115,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2630
+/* "pywrapfst.pyx":2632
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28129,7 +28130,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2631
+  /* "pywrapfst.pyx":2633
  * 
  *   cdef void _reserve_states(self, int64 n):
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
@@ -28138,11 +28139,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2631, __pyx_L1_error)
+    __PYX_ERR(0, 2633, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2630
+  /* "pywrapfst.pyx":2632
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28158,7 +28159,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2633
+/* "pywrapfst.pyx":2635
  *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28178,7 +28179,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_47reserve_states(PyObject *__p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2633, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2635, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -28201,7 +28202,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2645
+  /* "pywrapfst.pyx":2647
  *       self.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
@@ -28210,11 +28211,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_states");
-    __PYX_ERR(0, 2645, __pyx_L1_error)
+    __PYX_ERR(0, 2647, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n);
 
-  /* "pywrapfst.pyx":2646
+  /* "pywrapfst.pyx":2648
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -28226,7 +28227,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2633
+  /* "pywrapfst.pyx":2635
  *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28244,7 +28245,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2648
+/* "pywrapfst.pyx":2650
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -28273,7 +28274,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2649
+  /* "pywrapfst.pyx":2651
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
  *     cdef string _weight_type = self.weight_type()             # <<<<<<<<<<<<<<
@@ -28282,11 +28283,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2649, __pyx_L1_error)
+    __PYX_ERR(0, 2651, __pyx_L1_error)
   }
   __pyx_v__weight_type = ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0);
 
-  /* "pywrapfst.pyx":2651
+  /* "pywrapfst.pyx":2653
  *     cdef string _weight_type = self.weight_type()
  *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -28297,26 +28298,26 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
     __pyx_t_1 = __pyx_v_potentials; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2651, __pyx_L1_error)
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2653, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2651, __pyx_L1_error)
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2653, __pyx_L1_error)
   }
   for (;;) {
     if (likely(!__pyx_t_3)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
         if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2651, __pyx_L1_error)
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2653, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2651, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2653, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       } else {
         if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2651, __pyx_L1_error)
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2653, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2651, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2653, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
@@ -28326,7 +28327,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2651, __pyx_L1_error)
+          else __PYX_ERR(0, 2653, __pyx_L1_error)
         }
         break;
       }
@@ -28335,22 +28336,22 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
     __Pyx_XDECREF_SET(__pyx_v_weight, __pyx_t_4);
     __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":2652
+    /* "pywrapfst.pyx":2654
  *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:
  *       _potentials.push_back(_get_WeightClass_or_one(_weight_type, weight))             # <<<<<<<<<<<<<<
  *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()
  */
-    __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_v__weight_type, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2652, __pyx_L1_error)
+    __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_v__weight_type, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2654, __pyx_L1_error)
     try {
       __pyx_v__potentials.push_back(__pyx_t_5);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2652, __pyx_L1_error)
+      __PYX_ERR(0, 2654, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2651
+    /* "pywrapfst.pyx":2653
  *     cdef string _weight_type = self.weight_type()
  *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -28360,7 +28361,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2653
+  /* "pywrapfst.pyx":2655
  *     for weight in potentials:
  *       _potentials.push_back(_get_WeightClass_or_one(_weight_type, weight))
  *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
@@ -28369,11 +28370,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2653, __pyx_L1_error)
+    __PYX_ERR(0, 2655, __pyx_L1_error)
   }
   fst::script::Reweight(__pyx_v_self->_mfst.get(), __pyx_v__potentials, fst::script::GetReweightType(__pyx_v_to_final));
 
-  /* "pywrapfst.pyx":2654
+  /* "pywrapfst.pyx":2656
  *       _potentials.push_back(_get_WeightClass_or_one(_weight_type, weight))
  *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28382,11 +28383,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2654, __pyx_L1_error)
+    __PYX_ERR(0, 2656, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2654, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2656, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2648
+  /* "pywrapfst.pyx":2650
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -28405,7 +28406,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2656
+/* "pywrapfst.pyx":2658
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28452,7 +28453,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2656, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2658, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28465,14 +28466,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_s
     }
     __pyx_v_potentials = values[0];
     if (values[1]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2656, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2658, __pyx_L3_error)
     } else {
       __pyx_v_to_final = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2656, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2658, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28494,7 +28495,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2678
+  /* "pywrapfst.pyx":2680
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -28503,13 +28504,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reweight");
-    __PYX_ERR(0, 2678, __pyx_L1_error)
+    __PYX_ERR(0, 2680, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.to_final = __pyx_v_to_final;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reweight(__pyx_v_self, __pyx_v_potentials, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2678, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reweight(__pyx_v_self, __pyx_v_potentials, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2680, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2679
+  /* "pywrapfst.pyx":2681
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -28521,7 +28522,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2656
+  /* "pywrapfst.pyx":2658
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28539,7 +28540,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2681
+/* "pywrapfst.pyx":2683
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28550,7 +28551,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
 static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon *__pyx_optional_args) {
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":2683
+  /* "pywrapfst.pyx":2685
  *   cdef void _rmepsilon(self,
  *                        queue_type="auto",
  *                        bool connect=True,             # <<<<<<<<<<<<<<
@@ -28559,7 +28560,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
  */
   bool __pyx_v_connect = ((bool)1);
 
-  /* "pywrapfst.pyx":2684
+  /* "pywrapfst.pyx":2686
  *                        queue_type="auto",
  *                        bool connect=True,
  *                        weight=None,             # <<<<<<<<<<<<<<
@@ -28597,7 +28598,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2687
+  /* "pywrapfst.pyx":2689
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -28606,30 +28607,30 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2687, __pyx_L1_error)
+    __PYX_ERR(0, 2689, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2688
+  /* "pywrapfst.pyx":2690
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_zero(self.weight_type(),
  *                                                             weight)             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
  *     _opts.reset(
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2687, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2689, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2691
+  /* "pywrapfst.pyx":2693
  *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
  *     _opts.reset(
  *         new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
  *                                  connect,
  *                                  _weight,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2691, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2691, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2693, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2693, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2690
+  /* "pywrapfst.pyx":2692
  *                                                             weight)
  *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
  *     _opts.reset(             # <<<<<<<<<<<<<<
@@ -28638,7 +28639,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
  */
   __pyx_v__opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_connect, __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta));
 
-  /* "pywrapfst.pyx":2696
+  /* "pywrapfst.pyx":2698
  *                                  nstate,
  *                                  delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -28647,11 +28648,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2696, __pyx_L1_error)
+    __PYX_ERR(0, 2698, __pyx_L1_error)
   }
   fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":2697
+  /* "pywrapfst.pyx":2699
  *                                  delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(_opts))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28660,11 +28661,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2697, __pyx_L1_error)
+    __PYX_ERR(0, 2699, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2697, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2699, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2681
+  /* "pywrapfst.pyx":2683
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28680,7 +28681,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2699
+/* "pywrapfst.pyx":2701
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28708,7 +28709,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
     PyObject* values[5] = {0,0,0,0,0};
     values[0] = ((PyObject *)__pyx_n_u_auto);
 
-    /* "pywrapfst.pyx":2702
+    /* "pywrapfst.pyx":2704
  *                 queue_type="auto",
  *                 bool connect=True,
  *                 weight=None,             # <<<<<<<<<<<<<<
@@ -28766,7 +28767,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2699, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2701, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28786,10 +28787,10 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
     }
     __pyx_v_queue_type = values[0];
     if (values[1]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2701, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2703, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2701
+      /* "pywrapfst.pyx":2703
  *   def rmepsilon(self,
  *                 queue_type="auto",
  *                 bool connect=True,             # <<<<<<<<<<<<<<
@@ -28800,19 +28801,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
     }
     __pyx_v_weight = values[2];
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2703, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2705, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__22;
     }
     if (values[4]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2704, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2706, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__23;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2699, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2701, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28820,7 +28821,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_queue_type, __pyx_v_connect, __pyx_v_weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2699
+  /* "pywrapfst.pyx":2701
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28842,7 +28843,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2726
+  /* "pywrapfst.pyx":2728
  *       self.
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -28851,7 +28852,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_rmepsilon");
-    __PYX_ERR(0, 2726, __pyx_L1_error)
+    __PYX_ERR(0, 2728, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 5;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
@@ -28859,9 +28860,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   __pyx_t_1.weight = __pyx_v_weight;
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.delta = __pyx_v_delta;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2726, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2728, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2727
+  /* "pywrapfst.pyx":2729
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -28873,7 +28874,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2699
+  /* "pywrapfst.pyx":2701
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28891,7 +28892,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2729
+/* "pywrapfst.pyx":2731
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -28918,7 +28919,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2730
+  /* "pywrapfst.pyx":2732
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -28927,19 +28928,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2730, __pyx_L1_error)
+    __PYX_ERR(0, 2732, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2731
+    /* "pywrapfst.pyx":2733
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(self.weight_type(),
  *                                                           weight)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2731, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2733, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28953,14 +28954,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2731, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2733, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2731, __pyx_L1_error)
+    __PYX_ERR(0, 2733, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2730
+    /* "pywrapfst.pyx":2732
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -28969,7 +28970,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":2732
+  /* "pywrapfst.pyx":2734
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -28978,20 +28979,20 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2732, __pyx_L1_error)
+    __PYX_ERR(0, 2734, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2733
+  /* "pywrapfst.pyx":2735
  *       raise FstIndexError("State index out of range")
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(self.weight_type(),
  *                                                           weight)             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_one(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2732, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_one(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2734, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_5;
 
-  /* "pywrapfst.pyx":2734
+  /* "pywrapfst.pyx":2736
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(self.weight_type(),
  *                                                           weight)
  *     if not self._mfst.get().SetFinal(state, _weight):             # <<<<<<<<<<<<<<
@@ -29000,19 +29001,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2734, __pyx_L1_error)
+    __PYX_ERR(0, 2736, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v__weight) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2735
+    /* "pywrapfst.pyx":2737
  *                                                           weight)
  *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2735, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2737, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29026,14 +29027,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2735, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2737, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2735, __pyx_L1_error)
+    __PYX_ERR(0, 2737, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2734
+    /* "pywrapfst.pyx":2736
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(self.weight_type(),
  *                                                           weight)
  *     if not self._mfst.get().SetFinal(state, _weight):             # <<<<<<<<<<<<<<
@@ -29042,7 +29043,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":2736
+  /* "pywrapfst.pyx":2738
  *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -29051,11 +29052,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2736, __pyx_L1_error)
+    __PYX_ERR(0, 2738, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2736, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2738, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2729
+  /* "pywrapfst.pyx":2731
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -29074,7 +29075,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2738
+/* "pywrapfst.pyx":2740
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -29122,7 +29123,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2738, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2740, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29133,12 +29134,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2738, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2740, __pyx_L3_error)
     __pyx_v_weight = values[1];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2738, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2740, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29160,7 +29161,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2756
+  /* "pywrapfst.pyx":2758
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
@@ -29169,13 +29170,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_final");
-    __PYX_ERR(0, 2756, __pyx_L1_error)
+    __PYX_ERR(0, 2758, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.weight = __pyx_v_weight;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_final(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2756, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_final(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2758, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2757
+  /* "pywrapfst.pyx":2759
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -29187,7 +29188,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2738
+  /* "pywrapfst.pyx":2740
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -29205,7 +29206,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2759
+/* "pywrapfst.pyx":2761
  *     return self
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -29223,7 +29224,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2760
+  /* "pywrapfst.pyx":2762
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -29234,7 +29235,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2761
+    /* "pywrapfst.pyx":2763
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -29243,11 +29244,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2761, __pyx_L1_error)
+      __PYX_ERR(0, 2763, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2762
+    /* "pywrapfst.pyx":2764
  *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -29256,7 +29257,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2760
+    /* "pywrapfst.pyx":2762
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -29265,7 +29266,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":2763
+  /* "pywrapfst.pyx":2765
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
  *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
@@ -29274,16 +29275,16 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2763, __pyx_L1_error)
+    __PYX_ERR(0, 2765, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 2763, __pyx_L1_error)
+    __PYX_ERR(0, 2765, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2763, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2765, __pyx_L1_error)
   __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2759
+  /* "pywrapfst.pyx":2761
  *     return self
  * 
  *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -29299,7 +29300,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2765
+/* "pywrapfst.pyx":2767
  *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -29317,7 +29318,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2765, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2767, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -29337,7 +29338,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2779
+  /* "pywrapfst.pyx":2781
  *       self.
  *     """
  *     self._set_input_symbols(symbols)             # <<<<<<<<<<<<<<
@@ -29346,11 +29347,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 2779, __pyx_L1_error)
+    __PYX_ERR(0, 2781, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2779, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2781, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2780
+  /* "pywrapfst.pyx":2782
  *     """
  *     self._set_input_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -29362,7 +29363,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2765
+  /* "pywrapfst.pyx":2767
  *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -29380,7 +29381,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2782
+/* "pywrapfst.pyx":2784
  *     return self
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -29398,7 +29399,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2783
+  /* "pywrapfst.pyx":2785
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -29409,7 +29410,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2784
+    /* "pywrapfst.pyx":2786
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -29418,11 +29419,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2784, __pyx_L1_error)
+      __PYX_ERR(0, 2786, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2785
+    /* "pywrapfst.pyx":2787
  *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -29431,7 +29432,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2783
+    /* "pywrapfst.pyx":2785
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  *     if symbols is None:             # <<<<<<<<<<<<<<
@@ -29440,7 +29441,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
  */
   }
 
-  /* "pywrapfst.pyx":2786
+  /* "pywrapfst.pyx":2788
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
  *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
@@ -29449,16 +29450,16 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2786, __pyx_L1_error)
+    __PYX_ERR(0, 2788, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 2786, __pyx_L1_error)
+    __PYX_ERR(0, 2788, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2786, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2788, __pyx_L1_error)
   __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2782
+  /* "pywrapfst.pyx":2784
  *     return self
  * 
  *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
@@ -29474,7 +29475,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2788
+/* "pywrapfst.pyx":2790
  *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -29492,7 +29493,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2788, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2790, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
@@ -29512,7 +29513,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2802
+  /* "pywrapfst.pyx":2804
  *       self.
  *     """
  *     self._set_output_symbols(symbols)             # <<<<<<<<<<<<<<
@@ -29521,11 +29522,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 2802, __pyx_L1_error)
+    __PYX_ERR(0, 2804, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2802, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2804, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2803
+  /* "pywrapfst.pyx":2805
  *     """
  *     self._set_output_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -29537,7 +29538,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2788
+  /* "pywrapfst.pyx":2790
  *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
@@ -29555,7 +29556,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2805
+/* "pywrapfst.pyx":2807
  *     return self
  * 
  *   def set_properties(self, props, mask):             # <<<<<<<<<<<<<<
@@ -29598,11 +29599,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2805, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2807, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2805, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2807, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -29615,7 +29616,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2805, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2807, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29639,7 +29640,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2819
+  /* "pywrapfst.pyx":2821
  *       self.
  *     """
  *     self._mfst.get().SetProperties(props.value, mask.value)             # <<<<<<<<<<<<<<
@@ -29648,19 +29649,19 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2819, __pyx_L1_error)
+    __PYX_ERR(0, 2821, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_props, __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2819, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_props, __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2821, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_As_uint64_t(__pyx_t_1); if (unlikely((__pyx_t_2 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2819, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_As_uint64_t(__pyx_t_1); if (unlikely((__pyx_t_2 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2821, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2819, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_mask, __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2821, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_PyInt_As_uint64_t(__pyx_t_1); if (unlikely((__pyx_t_3 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2819, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_As_uint64_t(__pyx_t_1); if (unlikely((__pyx_t_3 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2821, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_self->_mfst.get()->SetProperties(__pyx_t_2, __pyx_t_3);
 
-  /* "pywrapfst.pyx":2820
+  /* "pywrapfst.pyx":2822
  *     """
  *     self._mfst.get().SetProperties(props.value, mask.value)
  *     return self             # <<<<<<<<<<<<<<
@@ -29672,7 +29673,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2805
+  /* "pywrapfst.pyx":2807
  *     return self
  * 
  *   def set_properties(self, props, mask):             # <<<<<<<<<<<<<<
@@ -29691,7 +29692,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2822
+/* "pywrapfst.pyx":2824
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29710,7 +29711,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2823
+  /* "pywrapfst.pyx":2825
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -29719,19 +29720,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2823, __pyx_L1_error)
+    __PYX_ERR(0, 2825, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2824
+    /* "pywrapfst.pyx":2826
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  * 
  *   def set_start(self, int64 state):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2824, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2826, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29745,14 +29746,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2824, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2826, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2824, __pyx_L1_error)
+    __PYX_ERR(0, 2826, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2823
+    /* "pywrapfst.pyx":2825
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -29761,7 +29762,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":2822
+  /* "pywrapfst.pyx":2824
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29780,7 +29781,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2826
+/* "pywrapfst.pyx":2828
  *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -29800,7 +29801,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_61set_start(PyObject *__pyx_v_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_start (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2826, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2828, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -29823,7 +29824,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2841
+  /* "pywrapfst.pyx":2843
  *       FstIndexError: State index out of range.
  *     """
  *     self._set_start(state)             # <<<<<<<<<<<<<<
@@ -29832,11 +29833,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_start");
-    __PYX_ERR(0, 2841, __pyx_L1_error)
+    __PYX_ERR(0, 2843, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_start(__pyx_v_self, __pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2841, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_start(__pyx_v_self, __pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2843, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2842
+  /* "pywrapfst.pyx":2844
  *     """
  *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
@@ -29848,7 +29849,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2826
+  /* "pywrapfst.pyx":2828
  *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -29866,7 +29867,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2844
+/* "pywrapfst.pyx":2846
  *     return self
  * 
  *   cdef void _topsort(self):             # <<<<<<<<<<<<<<
@@ -29885,7 +29886,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2846
+  /* "pywrapfst.pyx":2848
  *   cdef void _topsort(self):
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -29894,21 +29895,21 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2846, __pyx_L1_error)
+    __PYX_ERR(0, 2848, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2847
+    /* "pywrapfst.pyx":2849
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST")             # <<<<<<<<<<<<<<
  * 
  *   def topsort(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2847, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2849, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2847, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2849, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -29923,12 +29924,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_3, __pyx_kp_u_Cannot_topsort_cyclic_FST) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Cannot_topsort_cyclic_FST);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2847, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2849, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2846
+    /* "pywrapfst.pyx":2848
  *   cdef void _topsort(self):
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -29937,7 +29938,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2844
+  /* "pywrapfst.pyx":2846
  *     return self
  * 
  *   cdef void _topsort(self):             # <<<<<<<<<<<<<<
@@ -29956,7 +29957,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2849
+/* "pywrapfst.pyx":2851
  *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -29986,7 +29987,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2862
+  /* "pywrapfst.pyx":2864
  *        self.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -29995,11 +29996,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_topsort");
-    __PYX_ERR(0, 2862, __pyx_L1_error)
+    __PYX_ERR(0, 2864, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2863
+  /* "pywrapfst.pyx":2865
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
@@ -30011,7 +30012,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2849
+  /* "pywrapfst.pyx":2851
  *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -30029,7 +30030,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2865
+/* "pywrapfst.pyx":2867
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -30069,7 +30070,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2883
+  /* "pywrapfst.pyx":2885
  *     cdef Fst _fst2
  *     cdef vector[const_FstClass_ptr] _fsts2
  *     for _fst2 in fsts2:             # <<<<<<<<<<<<<<
@@ -30080,16 +30081,16 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   for (;;) {
     if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2883, __pyx_L1_error)
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2885, __pyx_L1_error)
     #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2883, __pyx_L1_error)
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2885, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     #endif
-    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 2883, __pyx_L1_error)
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 2885, __pyx_L1_error)
     __Pyx_XDECREF_SET(__pyx_v__fst2, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2884
+    /* "pywrapfst.pyx":2886
  *     cdef vector[const_FstClass_ptr] _fsts2
  *     for _fst2 in fsts2:
  *       _fsts2.push_back(_fst2._fst.get())             # <<<<<<<<<<<<<<
@@ -30098,16 +30099,16 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
  */
     if (unlikely(((PyObject *)__pyx_v__fst2) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2884, __pyx_L1_error)
+      __PYX_ERR(0, 2886, __pyx_L1_error)
     }
     try {
       __pyx_v__fsts2.push_back(__pyx_v__fst2->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2884, __pyx_L1_error)
+      __PYX_ERR(0, 2886, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2883
+    /* "pywrapfst.pyx":2885
  *     cdef Fst _fst2
  *     cdef vector[const_FstClass_ptr] _fsts2
  *     for _fst2 in fsts2:             # <<<<<<<<<<<<<<
@@ -30117,7 +30118,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2885
+  /* "pywrapfst.pyx":2887
  *     for _fst2 in fsts2:
  *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)             # <<<<<<<<<<<<<<
@@ -30126,11 +30127,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2885, __pyx_L1_error)
+    __PYX_ERR(0, 2887, __pyx_L1_error)
   }
   fst::script::Union(__pyx_v_self->_mfst.get(), __pyx_v__fsts2);
 
-  /* "pywrapfst.pyx":2886
+  /* "pywrapfst.pyx":2888
  *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -30139,11 +30140,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2886, __pyx_L1_error)
+    __PYX_ERR(0, 2888, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2886, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2888, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2887
+  /* "pywrapfst.pyx":2889
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()
  *     return self             # <<<<<<<<<<<<<<
@@ -30155,7 +30156,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2865
+  /* "pywrapfst.pyx":2867
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -30176,7 +30177,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2903
+/* "pywrapfst.pyx":2905
  *   """
  * 
  *   def __init__(self, arc_type="standard"):             # <<<<<<<<<<<<<<
@@ -30216,7 +30217,7 @@ static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2903, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2905, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -30230,7 +30231,7 @@ static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2903, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2905, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.VectorFst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -30258,17 +30259,17 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2905
+  /* "pywrapfst.pyx":2907
  *   def __init__(self, arc_type="standard"):
  *     cdef unique_ptr[fst.MutableFstClass] _tfst
  *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
  *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2905, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2907, __pyx_L1_error)
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2906
+  /* "pywrapfst.pyx":2908
  *     cdef unique_ptr[fst.MutableFstClass] _tfst
  *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *     if _tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30278,18 +30279,18 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   __pyx_t_2 = ((__pyx_v__tfst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2907
+    /* "pywrapfst.pyx":2909
  *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")             # <<<<<<<<<<<<<<
  *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2907, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2909, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2907, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2909, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2907, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2909, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -30305,14 +30306,14 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2907, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2909, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2907, __pyx_L1_error)
+    __PYX_ERR(0, 2909, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2906
+    /* "pywrapfst.pyx":2908
  *     cdef unique_ptr[fst.MutableFstClass] _tfst
  *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *     if _tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30321,7 +30322,7 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
   }
 
-  /* "pywrapfst.pyx":2908
+  /* "pywrapfst.pyx":2910
  *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  *     self._fst.reset(_tfst.release())             # <<<<<<<<<<<<<<
@@ -30330,11 +30331,11 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2908, __pyx_L1_error)
+    __PYX_ERR(0, 2910, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base.__pyx_base._fst.reset(__pyx_v__tfst.release());
 
-  /* "pywrapfst.pyx":2910
+  /* "pywrapfst.pyx":2912
  *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,
  *                                      fst.FstClass](self._fst)             # <<<<<<<<<<<<<<
@@ -30343,10 +30344,10 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2910, __pyx_L1_error)
+    __PYX_ERR(0, 2912, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2909
+  /* "pywrapfst.pyx":2911
  *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,             # <<<<<<<<<<<<<<
@@ -30355,11 +30356,11 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2909, __pyx_L1_error)
+    __PYX_ERR(0, 2911, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base._mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v_self->__pyx_base.__pyx_base._fst);
 
-  /* "pywrapfst.pyx":2903
+  /* "pywrapfst.pyx":2905
  *   """
  * 
  *   def __init__(self, arc_type="standard"):             # <<<<<<<<<<<<<<
@@ -30382,7 +30383,7 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2929
+/* "pywrapfst.pyx":2931
  * 
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30403,7 +30404,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2930
+  /* "pywrapfst.pyx":2932
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30413,14 +30414,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2931
+    /* "pywrapfst.pyx":2933
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef Fst _ofst = Fst.__new__(Fst)
  *   _ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2931, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2933, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30434,14 +30435,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2931, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2933, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2931, __pyx_L1_error)
+    __PYX_ERR(0, 2933, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2930
+    /* "pywrapfst.pyx":2932
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30450,19 +30451,19 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
  */
   }
 
-  /* "pywrapfst.pyx":2932
+  /* "pywrapfst.pyx":2934
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  *   cdef Fst _ofst = Fst.__new__(Fst)             # <<<<<<<<<<<<<<
  *   _ofst._fst.reset(tfst)
  *   return _ofst
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst_Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2932, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst_Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2934, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __pyx_v__ofst = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2933
+  /* "pywrapfst.pyx":2935
  *     raise FstOpError("Operation failed")
  *   cdef Fst _ofst = Fst.__new__(Fst)
  *   _ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -30471,11 +30472,11 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
  */
   if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2933, __pyx_L1_error)
+    __PYX_ERR(0, 2935, __pyx_L1_error)
   }
   __pyx_v__ofst->_fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2934
+  /* "pywrapfst.pyx":2936
  *   cdef Fst _ofst = Fst.__new__(Fst)
  *   _ofst._fst.reset(tfst)
  *   return _ofst             # <<<<<<<<<<<<<<
@@ -30487,7 +30488,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
   __pyx_r = __pyx_v__ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2929
+  /* "pywrapfst.pyx":2931
  * 
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30509,7 +30510,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2937
+/* "pywrapfst.pyx":2939
  * 
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30530,7 +30531,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2938
+  /* "pywrapfst.pyx":2940
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30540,14 +30541,14 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2939
+    /* "pywrapfst.pyx":2941
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
  *   _ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2939, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2941, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30561,14 +30562,14 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2939, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2941, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2939, __pyx_L1_error)
+    __PYX_ERR(0, 2941, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2938
+    /* "pywrapfst.pyx":2940
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -30577,19 +30578,19 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
  */
   }
 
-  /* "pywrapfst.pyx":2940
+  /* "pywrapfst.pyx":2942
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)             # <<<<<<<<<<<<<<
  *   _ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst_MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2940, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst_MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2942, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
   __pyx_v__ofst = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2941
+  /* "pywrapfst.pyx":2943
  *     raise FstOpError("Operation failed")
  *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
  *   _ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -30598,11 +30599,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
  */
   if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2941, __pyx_L1_error)
+    __PYX_ERR(0, 2943, __pyx_L1_error)
   }
   __pyx_v__ofst->__pyx_base._fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2944
+  /* "pywrapfst.pyx":2946
  *   # Makes a copy of it as the derived type! Cool.
  *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
  *                                     fst.FstClass](_ofst._fst)             # <<<<<<<<<<<<<<
@@ -30611,10 +30612,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
  */
   if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2944, __pyx_L1_error)
+    __PYX_ERR(0, 2946, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2943
+  /* "pywrapfst.pyx":2945
  *   _ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,             # <<<<<<<<<<<<<<
@@ -30623,11 +30624,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
  */
   if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2943, __pyx_L1_error)
+    __PYX_ERR(0, 2945, __pyx_L1_error)
   }
   __pyx_v__ofst->_mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v__ofst->__pyx_base._fst);
 
-  /* "pywrapfst.pyx":2945
+  /* "pywrapfst.pyx":2947
  *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
  *                                     fst.FstClass](_ofst._fst)
  *   return _ofst             # <<<<<<<<<<<<<<
@@ -30639,7 +30640,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
   __pyx_r = __pyx_v__ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2937
+  /* "pywrapfst.pyx":2939
  * 
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30661,7 +30662,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2948
+/* "pywrapfst.pyx":2950
  * 
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30679,7 +30680,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_XFst", 0);
 
-  /* "pywrapfst.pyx":2949
+  /* "pywrapfst.pyx":2951
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -30689,7 +30690,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kMutable, 1) == fst::kMutable) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2950
+    /* "pywrapfst.pyx":2952
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
@@ -30697,13 +30698,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  *     return _init_Fst(tfst)
  */
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(static_cast<__pyx_t_9pywrapfst_MutableFstClass_ptr>(__pyx_v_tfst))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2950, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(static_cast<__pyx_t_9pywrapfst_MutableFstClass_ptr>(__pyx_v_tfst))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2952, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2949
+    /* "pywrapfst.pyx":2951
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -30712,7 +30713,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  */
   }
 
-  /* "pywrapfst.pyx":2952
+  /* "pywrapfst.pyx":2954
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -30721,14 +30722,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  */
   /*else*/ {
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2952, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2954, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":2948
+  /* "pywrapfst.pyx":2950
  * 
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30747,7 +30748,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2955
+/* "pywrapfst.pyx":2957
  * 
  * 
  * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
@@ -30771,17 +30772,17 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst", 0);
 
-  /* "pywrapfst.pyx":2957
+  /* "pywrapfst.pyx":2959
  * cpdef Fst _read_Fst(source):
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
  *   if _tfst.get() == NULL:
  *     raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2957, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2959, __pyx_L1_error)
   __pyx_v__tfst.reset(fst::script::FstClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2958
+  /* "pywrapfst.pyx":2960
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30791,18 +30792,18 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
   __pyx_t_2 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2959
+    /* "pywrapfst.pyx":2961
  *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
  *   if _tfst.get() == NULL:
  *     raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
  *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2959, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2959, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2959, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -30818,14 +30819,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2959, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2961, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2959, __pyx_L1_error)
+    __PYX_ERR(0, 2961, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2958
+    /* "pywrapfst.pyx":2960
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30834,7 +30835,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
  */
   }
 
-  /* "pywrapfst.pyx":2960
+  /* "pywrapfst.pyx":2962
  *   if _tfst.get() == NULL:
  *     raise FstIOError(f"Read failed: {source!r}")
  *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -30842,13 +30843,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2960, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2962, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2955
+  /* "pywrapfst.pyx":2957
  * 
  * 
  * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
@@ -30892,7 +30893,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_s
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2955, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2957, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30909,7 +30910,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2963
+/* "pywrapfst.pyx":2965
  * 
  * 
  * cpdef Fst _read_Fst_from_string(string state):             # <<<<<<<<<<<<<<
@@ -30932,7 +30933,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
 
-  /* "pywrapfst.pyx":2965
+  /* "pywrapfst.pyx":2967
  * cpdef Fst _read_Fst_from_string(string state):
  *   cdef stringstream _sstrm
  *   _sstrm << state             # <<<<<<<<<<<<<<
@@ -30941,7 +30942,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
  */
   (void)((__pyx_v__sstrm << __pyx_v_state));
 
-  /* "pywrapfst.pyx":2967
+  /* "pywrapfst.pyx":2969
  *   _sstrm << state
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -30950,7 +30951,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
  */
   __pyx_v__tfst.reset(fst::script::FstClass::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":2968
+  /* "pywrapfst.pyx":2970
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30960,14 +30961,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
   __pyx_t_1 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2969
+    /* "pywrapfst.pyx":2971
  *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _tfst.get() == NULL:
  *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
  *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2969, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2971, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30981,14 +30982,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2969, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2971, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2969, __pyx_L1_error)
+    __PYX_ERR(0, 2971, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2968
+    /* "pywrapfst.pyx":2970
  *   cdef unique_ptr[fst.FstClass] _tfst
  *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30997,7 +30998,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
  */
   }
 
-  /* "pywrapfst.pyx":2970
+  /* "pywrapfst.pyx":2972
  *   if _tfst.get() == NULL:
  *     raise FstIOError("Read from string failed")
  *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -31005,13 +31006,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2970, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2972, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2963
+  /* "pywrapfst.pyx":2965
  * 
  * 
  * cpdef Fst _read_Fst_from_string(string state):             # <<<<<<<<<<<<<<
@@ -31043,7 +31044,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_sel
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_Fst_from_string (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2963, __pyx_L3_error)
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2965, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31067,7 +31068,7 @@ static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2963, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2965, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31084,7 +31085,7 @@ static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3089
+/* "pywrapfst.pyx":3091
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -31118,7 +31119,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3090
+  /* "pywrapfst.pyx":3092
  * 
  *   def __repr__(self):
  *     return f"<Arc at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -31126,7 +31127,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3090, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -31134,9 +31135,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __pyx_t_2 += 10;
   __Pyx_GIVEREF(__pyx_kp_u_Arc_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Arc_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3090, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3090, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -31148,14 +31149,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3090, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3089
+  /* "pywrapfst.pyx":3091
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -31176,7 +31177,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3092
+/* "pywrapfst.pyx":3094
  *     return f"<Arc at 0x{id(self):x}>"
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -31224,23 +31225,23 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_olabel)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3092, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3094, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3092, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3094, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
         if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nextstate)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3092, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3094, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3092, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3094, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -31250,14 +31251,14 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
       values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
       values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
     }
-    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3092, __pyx_L3_error)
-    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3092, __pyx_L3_error)
+    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3094, __pyx_L3_error)
+    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3094, __pyx_L3_error)
     __pyx_v_weight = values[2];
-    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3092, __pyx_L3_error)
+    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3094, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3092, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3094, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -31280,17 +31281,17 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3093
+  /* "pywrapfst.pyx":3095
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(b"tropical", weight)             # <<<<<<<<<<<<<<
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3093, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3095, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3094
+  /* "pywrapfst.pyx":3096
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  *     cdef fst.WeightClass _weight = _get_WeightClass_or_one(b"tropical", weight)
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))             # <<<<<<<<<<<<<<
@@ -31299,11 +31300,11 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3094, __pyx_L1_error)
+    __PYX_ERR(0, 3096, __pyx_L1_error)
   }
   __pyx_v_self->_arc.reset(new fst::script::ArcClass(__pyx_v_ilabel, __pyx_v_olabel, __pyx_v__weight, __pyx_v_nextstate));
 
-  /* "pywrapfst.pyx":3092
+  /* "pywrapfst.pyx":3094
  *     return f"<Arc at 0x{id(self):x}>"
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -31322,7 +31323,7 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3096
+/* "pywrapfst.pyx":3098
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -31352,7 +31353,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3096, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3098, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Arc_5copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -31369,10 +31370,10 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3096, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3098, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3096, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3098, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -31391,7 +31392,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":3097
+  /* "pywrapfst.pyx":3099
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -31399,15 +31400,15 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
  *   property ilabel:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_nextstate); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_nextstate); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -31421,14 +31422,14 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
   __pyx_t_2 = 0;
   __pyx_t_3 = 0;
   __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3097, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3099, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3096
+  /* "pywrapfst.pyx":3098
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -31473,7 +31474,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3096, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3098, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31490,7 +31491,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3101
+/* "pywrapfst.pyx":3103
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31520,7 +31521,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3102
+  /* "pywrapfst.pyx":3104
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -31530,15 +31531,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3102, __pyx_L1_error)
+    __PYX_ERR(0, 3104, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3102, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3104, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3101
+  /* "pywrapfst.pyx":3103
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31557,7 +31558,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3104
+/* "pywrapfst.pyx":3106
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31576,7 +31577,7 @@ static int __pyx_pw_9pywrapfst_3Arc_6ilabel_3__set__(PyObject *__pyx_v_self, PyO
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3104, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3106, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31599,7 +31600,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3105
+  /* "pywrapfst.pyx":3107
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -31608,11 +31609,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3105, __pyx_L1_error)
+    __PYX_ERR(0, 3107, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3104
+  /* "pywrapfst.pyx":3106
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31631,7 +31632,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3109
+/* "pywrapfst.pyx":3111
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31661,7 +31662,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3110
+  /* "pywrapfst.pyx":3112
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -31671,15 +31672,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3110, __pyx_L1_error)
+    __PYX_ERR(0, 3112, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3110, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3112, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3109
+  /* "pywrapfst.pyx":3111
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31698,7 +31699,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3112
+/* "pywrapfst.pyx":3114
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31717,7 +31718,7 @@ static int __pyx_pw_9pywrapfst_3Arc_6olabel_3__set__(PyObject *__pyx_v_self, PyO
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3112, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3114, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31740,7 +31741,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3113
+  /* "pywrapfst.pyx":3115
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -31749,11 +31750,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3113, __pyx_L1_error)
+    __PYX_ERR(0, 3115, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3112
+  /* "pywrapfst.pyx":3114
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31772,7 +31773,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3117
+/* "pywrapfst.pyx":3119
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31803,19 +31804,19 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3118
+  /* "pywrapfst.pyx":3120
  * 
  *     def __get__(self):
  *       cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3118, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3120, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3119
+  /* "pywrapfst.pyx":3121
  *     def __get__(self):
  *       cdef Weight _weight = Weight.__new__(Weight)
  *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
@@ -31824,15 +31825,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3119, __pyx_L1_error)
+    __PYX_ERR(0, 3121, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3119, __pyx_L1_error)
+    __PYX_ERR(0, 3121, __pyx_L1_error)
   }
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":3120
+  /* "pywrapfst.pyx":3122
  *       cdef Weight _weight = Weight.__new__(Weight)
  *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return _weight             # <<<<<<<<<<<<<<
@@ -31844,7 +31845,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3117
+  /* "pywrapfst.pyx":3119
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31864,7 +31865,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3122
+/* "pywrapfst.pyx":3124
  *       return _weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -31894,21 +31895,21 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3123
+  /* "pywrapfst.pyx":3125
  * 
  *     def __set__(self, weight):
  *       deref(self._arc).weight = _get_WeightClass_or_one(b"tropical", weight)             # <<<<<<<<<<<<<<
  * 
  *   property nextstate:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3123, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_one(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3125, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3123, __pyx_L1_error)
+    __PYX_ERR(0, 3125, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3122
+  /* "pywrapfst.pyx":3124
  *       return _weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -31927,7 +31928,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3127
+/* "pywrapfst.pyx":3129
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31957,7 +31958,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3128
+  /* "pywrapfst.pyx":3130
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -31967,15 +31968,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3128, __pyx_L1_error)
+    __PYX_ERR(0, 3130, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3128, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3130, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3127
+  /* "pywrapfst.pyx":3129
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31994,7 +31995,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3130
+/* "pywrapfst.pyx":3132
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -32013,7 +32014,7 @@ static int __pyx_pw_9pywrapfst_3Arc_9nextstate_3__set__(PyObject *__pyx_v_self,
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3130, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3132, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -32036,7 +32037,7 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3131
+  /* "pywrapfst.pyx":3133
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -32045,11 +32046,11 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3131, __pyx_L1_error)
+    __PYX_ERR(0, 3133, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3130
+  /* "pywrapfst.pyx":3132
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -32181,7 +32182,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3134
+/* "pywrapfst.pyx":3136
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -32202,19 +32203,19 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_Arc", 0);
 
-  /* "pywrapfst.pyx":3135
+  /* "pywrapfst.pyx":3137
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   _weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3135, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3137, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3136
+  /* "pywrapfst.pyx":3138
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
@@ -32223,11 +32224,11 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  */
   if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3136, __pyx_L1_error)
+    __PYX_ERR(0, 3138, __pyx_L1_error)
   }
   __pyx_v__weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":3137
+  /* "pywrapfst.pyx":3139
  *   cdef Weight _weight = Weight.__new__(Weight)
  *   _weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)             # <<<<<<<<<<<<<<
@@ -32235,13 +32236,13 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3137, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3137, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3137, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3137, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
@@ -32255,14 +32256,14 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
   __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3137, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3134
+  /* "pywrapfst.pyx":3136
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -32285,28 +32286,28 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3148
+/* "pywrapfst.pyx":3153
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<ArcIterator at 0x{id(self):x}>"
+ *     return f"<_ArcIterator at 0x{id(self):x}>"
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator___repr__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator___repr__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator___repr__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -32319,25 +32320,25 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3149
+  /* "pywrapfst.pyx":3154
  * 
  *   def __repr__(self):
- *     return f"<ArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
+ *     return f"<_ArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, Fst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3149, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
   __Pyx_INCREF(__pyx_kp_u_ArcIterator_at_0x);
-  __pyx_t_2 += 18;
+  __pyx_t_2 += 19;
   __Pyx_GIVEREF(__pyx_kp_u_ArcIterator_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_ArcIterator_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3149, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3149, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -32349,18 +32350,18 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3149, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3148
+  /* "pywrapfst.pyx":3153
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<ArcIterator at 0x{id(self):x}>"
+ *     return f"<_ArcIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -32369,7 +32370,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -32377,8 +32378,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3151
- *     return f"<ArcIterator at 0x{id(self):x}>"
+/* "pywrapfst.pyx":3156
+ *     return f"<_ArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -32386,8 +32387,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static int __pyx_pw_9pywrapfst_12_ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_9pywrapfst_12_ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   int64 __pyx_v_state;
   int __pyx_lineno = 0;
@@ -32419,11 +32420,11 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3151, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3156, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3151, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3156, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32432,18 +32433,18 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3151, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3156, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3151, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3156, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3151, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_2__init__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3156, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_2__init__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
 
   /* function exit code */
   goto __pyx_L0;
@@ -32454,7 +32455,7 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state) {
+static int __pyx_pf_9pywrapfst_12_ArcIterator_2__init__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -32467,7 +32468,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3152
+  /* "pywrapfst.pyx":3157
  * 
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32476,19 +32477,19 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3152, __pyx_L1_error)
+    __PYX_ERR(0, 3157, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3153
+    /* "pywrapfst.pyx":3158
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3153, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3158, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32502,14 +32503,14 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3153, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3158, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 3153, __pyx_L1_error)
+    __PYX_ERR(0, 3158, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3152
+    /* "pywrapfst.pyx":3157
  * 
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32518,7 +32519,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":3155
+  /* "pywrapfst.pyx":3160
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -32527,16 +32528,16 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3155, __pyx_L1_error)
+    __PYX_ERR(0, 3160, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3155, __pyx_L1_error)
+    __PYX_ERR(0, 3160, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3156
+  /* "pywrapfst.pyx":3161
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  *     self._aiter.reset(new fst.ArcIteratorClass(deref(self._fst), state))             # <<<<<<<<<<<<<<
@@ -32545,16 +32546,16 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3156, __pyx_L1_error)
+    __PYX_ERR(0, 3161, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3156, __pyx_L1_error)
+    __PYX_ERR(0, 3161, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3151
- *     return f"<ArcIterator at 0x{id(self):x}>"
+  /* "pywrapfst.pyx":3156
+ *     return f"<_ArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -32568,14 +32569,14 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3159
+/* "pywrapfst.pyx":3164
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32584,24 +32585,24 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_5__iter__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_5__iter__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_4__iter__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_4__iter__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_4__iter__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3160
+  /* "pywrapfst.pyx":3165
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -32613,7 +32614,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3159
+  /* "pywrapfst.pyx":3164
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32628,7 +32629,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3163
+/* "pywrapfst.pyx":3168
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32637,19 +32638,19 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_7__next__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_7__next__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_6__next__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_6__next__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_6__next__(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_v_result = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -32660,7 +32661,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3164
+  /* "pywrapfst.pyx":3169
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32669,12 +32670,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3164, __pyx_L1_error)
+    __PYX_ERR(0, 3169, __pyx_L1_error)
   }
-  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
+  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst__ArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3165
+    /* "pywrapfst.pyx":3170
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -32682,9 +32683,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  *     self.next()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 3165, __pyx_L1_error)
+    __PYX_ERR(0, 3170, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3164
+    /* "pywrapfst.pyx":3169
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32693,7 +32694,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":3166
+  /* "pywrapfst.pyx":3171
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -32702,14 +32703,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3166, __pyx_L1_error)
+    __PYX_ERR(0, 3171, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3166, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__ArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3171, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3167
+  /* "pywrapfst.pyx":3172
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -32718,11 +32719,11 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3167, __pyx_L1_error)
+    __PYX_ERR(0, 3172, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
+  ((struct __pyx_vtabstruct_9pywrapfst__ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3168
+  /* "pywrapfst.pyx":3173
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -32734,7 +32735,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3163
+  /* "pywrapfst.pyx":3168
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32745,7 +32746,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_result);
@@ -32754,7 +32755,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3170
+/* "pywrapfst.pyx":3175
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32762,8 +32763,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  *     done(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static bool __pyx_f_9pywrapfst_12_ArcIterator_done(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -32784,9 +32785,9 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3170, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3175, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_9done)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32800,10 +32801,10 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3170, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3175, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3170, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3175, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32822,7 +32823,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3179
+  /* "pywrapfst.pyx":3184
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -32831,12 +32832,12 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3179, __pyx_L1_error)
+    __PYX_ERR(0, 3184, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3170
+  /* "pywrapfst.pyx":3175
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32850,7 +32851,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -32858,20 +32859,20 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("done (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_8done(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_8done(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_8done(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -32880,7 +32881,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_11ArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3170, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_12_ArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3175, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32889,7 +32890,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -32897,7 +32898,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3181
+/* "pywrapfst.pyx":3186
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32905,8 +32906,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
  *     flags(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static uint8 __pyx_f_9pywrapfst_12_ArcIterator_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -32927,9 +32928,9 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3181, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3186, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_11flags)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_11flags)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32943,10 +32944,10 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3181, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3186, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3181, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3186, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32965,7 +32966,7 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3190
+  /* "pywrapfst.pyx":3195
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -32974,12 +32975,12 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3190, __pyx_L1_error)
+    __PYX_ERR(0, 3195, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3181
+  /* "pywrapfst.pyx":3186
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32993,7 +32994,7 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -33001,20 +33002,20 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_10flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_10flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("flags (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_10flags(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_10flags(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_10flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33023,7 +33024,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3181, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12_ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3186, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33032,7 +33033,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33040,7 +33041,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3192
+/* "pywrapfst.pyx":3197
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33048,8 +33049,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
  *     next(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_next(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -33068,9 +33069,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3192, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3197, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_13next)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_13next)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33084,7 +33085,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3192, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3197, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33104,7 +33105,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3198
+  /* "pywrapfst.pyx":3203
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -33113,11 +33114,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3198, __pyx_L1_error)
+    __PYX_ERR(0, 3203, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3192
+  /* "pywrapfst.pyx":3197
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33132,26 +33133,26 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_12next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_12next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("next (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_12next(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_12next(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_12next(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33160,7 +33161,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3192, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_12_ArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3197, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33169,7 +33170,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33177,7 +33178,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3200
+/* "pywrapfst.pyx":3205
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33185,8 +33186,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
  *     position(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static size_t __pyx_f_9pywrapfst_12_ArcIterator_position(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33207,9 +33208,9 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3205, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_15position)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_15position)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33223,10 +33224,10 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3200, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3205, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3200, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3205, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -33245,7 +33246,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3209
+  /* "pywrapfst.pyx":3214
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -33254,12 +33255,12 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3209, __pyx_L1_error)
+    __PYX_ERR(0, 3214, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3200
+  /* "pywrapfst.pyx":3205
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33273,7 +33274,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -33281,20 +33282,20 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_14position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_14position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("position (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_14position(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_14position(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_14position(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33303,7 +33304,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_11ArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_12_ArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3205, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33312,7 +33313,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33320,7 +33321,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3211
+/* "pywrapfst.pyx":3216
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33328,8 +33329,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
  *     reset(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_reset(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -33348,9 +33349,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3211, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3216, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_17reset)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_17reset)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33364,7 +33365,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3211, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3216, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33384,7 +33385,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     #endif
   }
 
-  /* "pywrapfst.pyx":3217
+  /* "pywrapfst.pyx":3222
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -33393,11 +33394,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3217, __pyx_L1_error)
+    __PYX_ERR(0, 3222, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3211
+  /* "pywrapfst.pyx":3216
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33412,26 +33413,26 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_16reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_16reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reset (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_16reset(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_16reset(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_16reset(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33440,7 +33441,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3211, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_12_ArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3216, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33449,7 +33450,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33457,7 +33458,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3219
+/* "pywrapfst.pyx":3224
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33465,8 +33466,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
  *     seek(self, a)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_seek(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -33486,10 +33487,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3219, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3224, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_19seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3219, __pyx_L1_error)
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_19seek)) {
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3224, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33505,7 +33506,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3219, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3224, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33525,7 +33526,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3228
+  /* "pywrapfst.pyx":3233
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -33534,11 +33535,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3228, __pyx_L1_error)
+    __PYX_ERR(0, 3233, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3219
+  /* "pywrapfst.pyx":3224
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33554,15 +33555,15 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
@@ -33571,22 +33572,22 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3219, __pyx_L3_error)
+    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3224, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_18seek(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_18seek(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_18seek(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, size_t __pyx_v_a) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33595,7 +33596,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3219, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_12_ArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33604,7 +33605,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33612,7 +33613,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3230
+/* "pywrapfst.pyx":3235
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33620,8 +33621,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
  *     set_flags(self, flags, mask)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static void __pyx_f_9pywrapfst_12_ArcIterator_set_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -33644,12 +33645,12 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3230, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3235, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_21set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3230, __pyx_L1_error)
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_21set_flags)) {
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3235, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3230, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3235, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -33667,7 +33668,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3230, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3235, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33677,7 +33678,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3230, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3235, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33685,7 +33686,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3230, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3235, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -33696,7 +33697,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
           PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3230, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3235, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -33718,7 +33719,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":3240
+  /* "pywrapfst.pyx":3245
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -33727,11 +33728,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3240, __pyx_L1_error)
+    __PYX_ERR(0, 3245, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3230
+  /* "pywrapfst.pyx":3235
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33749,15 +33750,15 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_WriteUnraisable("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint8 __pyx_v_flags;
   uint8 __pyx_v_mask;
   int __pyx_lineno = 0;
@@ -33789,11 +33790,11 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3230, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3235, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3230, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3235, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -33801,25 +33802,25 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3230, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3230, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3235, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3235, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3230, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3235, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_20set_flags(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_20set_flags(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33828,7 +33829,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3230, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_12_ArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3235, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33837,7 +33838,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33845,7 +33846,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3242
+/* "pywrapfst.pyx":3247
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33853,8 +33854,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
  *     value(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_12_ArcIterator_value(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33874,9 +33875,9 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3242, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3247, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_23value)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_ArcIterator_23value)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -33891,7 +33892,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3242, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3247, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -33912,7 +33913,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3248
+  /* "pywrapfst.pyx":3253
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -33922,15 +33923,15 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3248, __pyx_L1_error)
+    __PYX_ERR(0, 3253, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3248, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3253, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3242
+  /* "pywrapfst.pyx":3247
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33944,7 +33945,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33953,20 +33954,20 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_22value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_ArcIterator_22value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("value (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_22value(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_22value(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_22value(struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33975,7 +33976,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3242, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_12_ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3247, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33984,7 +33985,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -33999,19 +34000,19 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_25__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_25__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_25__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_25__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_24__reduce_cython__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34041,7 +34042,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UN
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
@@ -34056,19 +34057,19 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UN
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_27__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_27__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_27__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_ArcIterator_27__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __pyx_r = __pyx_pf_9pywrapfst_12_ArcIterator_26__setstate_cython__(((struct __pyx_obj_9pywrapfst__ArcIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_12_ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34098,35 +34099,35 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.ArcIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._ArcIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3260
+/* "pywrapfst.pyx":3265
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<MutableArcIterator at 0x{id(self):x}>"
+ *     return f"<_MutableArcIterator at 0x{id(self):x}>"
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator___repr__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator___repr__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34139,25 +34140,25 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3261
+  /* "pywrapfst.pyx":3266
  * 
  *   def __repr__(self):
- *     return f"<MutableArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
+ *     return f"<_MutableArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3261, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3266, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
   __Pyx_INCREF(__pyx_kp_u_MutableArcIterator_at_0x);
-  __pyx_t_2 += 25;
+  __pyx_t_2 += 26;
   __Pyx_GIVEREF(__pyx_kp_u_MutableArcIterator_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_MutableArcIterator_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3261, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3266, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3261, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3266, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -34169,18 +34170,18 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3261, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3266, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3260
+  /* "pywrapfst.pyx":3265
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<MutableArcIterator at 0x{id(self):x}>"
+ *     return f"<_MutableArcIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -34189,7 +34190,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -34197,8 +34198,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3263
- *     return f"<MutableArcIterator at 0x{id(self):x}>"
+/* "pywrapfst.pyx":3268
+ *     return f"<_MutableArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -34206,8 +34207,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static int __pyx_pw_9pywrapfst_19_MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_9pywrapfst_19_MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst = 0;
   int64 __pyx_v_state;
   int __pyx_lineno = 0;
@@ -34239,11 +34240,11 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3263, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3268, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3263, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3268, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -34252,18 +34253,18 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_MutableFst *)values[0]);
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3263, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3268, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3263, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3268, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3263, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3268, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_2__init__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
 
   /* function exit code */
   goto __pyx_L0;
@@ -34274,7 +34275,7 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state) {
+static int __pyx_pf_9pywrapfst_19_MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -34287,7 +34288,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3264
+  /* "pywrapfst.pyx":3269
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -34296,19 +34297,19 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3264, __pyx_L1_error)
+    __PYX_ERR(0, 3269, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3265
+    /* "pywrapfst.pyx":3270
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3265, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3270, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -34322,14 +34323,14 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3265, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3270, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 3265, __pyx_L1_error)
+    __PYX_ERR(0, 3270, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3264
+    /* "pywrapfst.pyx":3269
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -34338,7 +34339,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":3267
+  /* "pywrapfst.pyx":3272
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -34347,16 +34348,16 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3267, __pyx_L1_error)
+    __PYX_ERR(0, 3272, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_mfst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3267, __pyx_L1_error)
+    __PYX_ERR(0, 3272, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3268
+  /* "pywrapfst.pyx":3273
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst
  *     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))             # <<<<<<<<<<<<<<
@@ -34365,16 +34366,16 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3268, __pyx_L1_error)
+    __PYX_ERR(0, 3273, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3268, __pyx_L1_error)
+    __PYX_ERR(0, 3273, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3263
- *     return f"<MutableArcIterator at 0x{id(self):x}>"
+  /* "pywrapfst.pyx":3268
+ *     return f"<_MutableArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -34388,15 +34389,15 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
-static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
+static PyObject *__pyx_gb_9pywrapfst_19_MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "pywrapfst.pyx":3271
+/* "pywrapfst.pyx":3276
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34405,19 +34406,19 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_5__iter__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_4__iter__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -34429,7 +34430,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 3271, __pyx_L1_error)
+    __PYX_ERR(0, 3276, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -34437,7 +34438,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_18MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3271, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_19_MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3276, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -34445,7 +34446,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
   __Pyx_XGIVEREF(__pyx_r);
@@ -34453,7 +34454,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   return __pyx_r;
 }
 
-static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
+static PyObject *__pyx_gb_9pywrapfst_19_MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
 {
   struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *__pyx_cur_scope = ((struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *)__pyx_generator->closure);
   PyObject *__pyx_r = NULL;
@@ -34472,9 +34473,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3271, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3276, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3272
+  /* "pywrapfst.pyx":3277
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):
  *     while not self.done():             # <<<<<<<<<<<<<<
@@ -34484,12 +34485,12 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   while (1) {
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-      __PYX_ERR(0, 3272, __pyx_L1_error)
+      __PYX_ERR(0, 3277, __pyx_L1_error)
     }
-    __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->done(__pyx_cur_scope->__pyx_v_self, 0) != 0)) != 0);
+    __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->done(__pyx_cur_scope->__pyx_v_self, 0) != 0)) != 0);
     if (!__pyx_t_1) break;
 
-    /* "pywrapfst.pyx":3273
+    /* "pywrapfst.pyx":3278
  *   def __iter__(self):
  *     while not self.done():
  *       yield self.value()             # <<<<<<<<<<<<<<
@@ -34498,9 +34499,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-      __PYX_ERR(0, 3273, __pyx_L1_error)
+      __PYX_ERR(0, 3278, __pyx_L1_error)
     }
-    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3273, __pyx_L1_error)
+    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3278, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -34511,24 +34512,24 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     __pyx_generator->resume_label = 1;
     return __pyx_r;
     __pyx_L6_resume_from_yield:;
-    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3273, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3278, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3274
+    /* "pywrapfst.pyx":3279
  *     while not self.done():
  *       yield self.value()
  *       self.next()             # <<<<<<<<<<<<<<
  * 
- *   cpdef bool done(self):
+ *   # Magic method used to get a Pythonic API out of the C++ API.
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-      __PYX_ERR(0, 3274, __pyx_L1_error)
+      __PYX_ERR(0, 3279, __pyx_L1_error)
     }
-    ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->next(__pyx_cur_scope->__pyx_v_self, 0);
+    ((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->next(__pyx_cur_scope->__pyx_v_self, 0);
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "pywrapfst.pyx":3271
+  /* "pywrapfst.pyx":3276
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34553,16 +34554,142 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3276
- *       self.next()
+/* "pywrapfst.pyx":3282
+ * 
+ *   # Magic method used to get a Pythonic API out of the C++ API.
+ *   def __next__(self):             # <<<<<<<<<<<<<<
+ *     if self.done():
+ *       raise StopIteration
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_7__next__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_7__next__(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
+  PyObject *__pyx_v_result = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__next__", 0);
+
+  /* "pywrapfst.pyx":3283
+ *   # Magic method used to get a Pythonic API out of the C++ API.
+ *   def __next__(self):
+ *     if self.done():             # <<<<<<<<<<<<<<
+ *       raise StopIteration
+ *     result = self.value()
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
+    __PYX_ERR(0, 3283, __pyx_L1_error)
+  }
+  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
+  if (unlikely(__pyx_t_1)) {
+
+    /* "pywrapfst.pyx":3284
+ *   def __next__(self):
+ *     if self.done():
+ *       raise StopIteration             # <<<<<<<<<<<<<<
+ *     result = self.value()
+ *     self.next()
+ */
+    __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
+    __PYX_ERR(0, 3284, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":3283
+ *   # Magic method used to get a Pythonic API out of the C++ API.
+ *   def __next__(self):
+ *     if self.done():             # <<<<<<<<<<<<<<
+ *       raise StopIteration
+ *     result = self.value()
+ */
+  }
+
+  /* "pywrapfst.pyx":3285
+ *     if self.done():
+ *       raise StopIteration
+ *     result = self.value()             # <<<<<<<<<<<<<<
+ *     self.next()
+ *     return result
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
+    __PYX_ERR(0, 3285, __pyx_L1_error)
+  }
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3285, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v_result = __pyx_t_2;
+  __pyx_t_2 = 0;
+
+  /* "pywrapfst.pyx":3286
+ *       raise StopIteration
+ *     result = self.value()
+ *     self.next()             # <<<<<<<<<<<<<<
+ *     return result
+ * 
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
+    __PYX_ERR(0, 3286, __pyx_L1_error)
+  }
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
+
+  /* "pywrapfst.pyx":3287
+ *     result = self.value()
+ *     self.next()
+ *     return result             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef bool done(self):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_result);
+  __pyx_r = __pyx_v_result;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":3282
+ * 
+ *   # Magic method used to get a Pythonic API out of the C++ API.
+ *   def __next__(self):             # <<<<<<<<<<<<<<
+ *     if self.done():
+ *       raise StopIteration
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_result);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":3289
+ *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
  *     """
  *     done(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_8done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_10done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static bool __pyx_f_9pywrapfst_19_MutableArcIterator_done(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34583,9 +34710,9 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3276, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3289, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_8done)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_10done)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -34599,10 +34726,10 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3276, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3289, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3276, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3289, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34621,7 +34748,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3285
+  /* "pywrapfst.pyx":3298
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -34630,13 +34757,13 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3285, __pyx_L1_error)
+    __PYX_ERR(0, 3298, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3276
- *       self.next()
+  /* "pywrapfst.pyx":3289
+ *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
  *     """
@@ -34649,7 +34776,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -34657,20 +34784,20 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_8done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_7done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_8done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_10done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_9done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_10done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("done (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_7done(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_9done(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_9done(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34679,7 +34806,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_18MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3276, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_19_MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34688,7 +34815,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -34696,7 +34823,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3287
+/* "pywrapfst.pyx":3300
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34704,8 +34831,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
  *     flags(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_10flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_12flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static uint8 __pyx_f_9pywrapfst_19_MutableArcIterator_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34726,9 +34853,9 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3287, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3300, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_10flags)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_12flags)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -34742,10 +34869,10 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3287, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3300, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3287, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3300, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34764,7 +34891,7 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":3296
+  /* "pywrapfst.pyx":3309
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -34773,12 +34900,12 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3296, __pyx_L1_error)
+    __PYX_ERR(0, 3309, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3287
+  /* "pywrapfst.pyx":3300
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34792,7 +34919,7 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -34800,20 +34927,20 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_10flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_9flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_10flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_12flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_11flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_12flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("flags (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_9flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_11flags(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_11flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34822,7 +34949,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3287, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_19_MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3300, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34831,7 +34958,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -34839,7 +34966,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3298
+/* "pywrapfst.pyx":3311
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34847,8 +34974,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
  *     next(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_12next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_14next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_next(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -34867,9 +34994,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3298, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3311, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_12next)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_14next)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -34883,7 +35010,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3298, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3311, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -34903,7 +35030,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3304
+  /* "pywrapfst.pyx":3317
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -34912,11 +35039,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3304, __pyx_L1_error)
+    __PYX_ERR(0, 3317, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3298
+  /* "pywrapfst.pyx":3311
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34931,26 +35058,26 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_12next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_11next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_12next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_14next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_13next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_14next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("next (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_11next(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_13next(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_13next(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -34959,7 +35086,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3298, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3311, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34968,7 +35095,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -34976,7 +35103,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3306
+/* "pywrapfst.pyx":3319
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -34984,8 +35111,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
  *     position(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_14position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_16position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static size_t __pyx_f_9pywrapfst_19_MutableArcIterator_position(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35006,9 +35133,9 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3306, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3319, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_14position)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_16position)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -35022,10 +35149,10 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3306, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3319, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3306, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3319, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -35044,7 +35171,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3315
+  /* "pywrapfst.pyx":3328
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -35053,12 +35180,12 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3315, __pyx_L1_error)
+    __PYX_ERR(0, 3328, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3306
+  /* "pywrapfst.pyx":3319
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -35072,7 +35199,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -35080,20 +35207,20 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_14position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_13position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_14position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_16position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_15position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_16position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("position (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_13position(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_15position(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_15position(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35102,7 +35229,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_18MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3306, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_19_MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3319, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35111,7 +35238,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.position", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35119,7 +35246,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3317
+/* "pywrapfst.pyx":3330
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35127,8 +35254,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
  *     reset(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_16reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_18reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_reset(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -35147,9 +35274,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3317, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3330, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_16reset)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_18reset)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -35163,7 +35290,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3317, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3330, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35183,7 +35310,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":3323
+  /* "pywrapfst.pyx":3336
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -35192,11 +35319,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3323, __pyx_L1_error)
+    __PYX_ERR(0, 3336, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3317
+  /* "pywrapfst.pyx":3330
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35211,26 +35338,26 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_16reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_15reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_16reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_18reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_17reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_18reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reset (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_15reset(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_17reset(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_17reset(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35239,7 +35366,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3317, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3330, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35248,7 +35375,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35256,7 +35383,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3325
+/* "pywrapfst.pyx":3338
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -35264,8 +35391,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
  *     seek(self, a)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_20seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_seek(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -35285,10 +35412,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3325, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3338, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_18seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3325, __pyx_L1_error)
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_20seek)) {
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3338, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -35304,7 +35431,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3325, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3338, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35324,7 +35451,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3334
+  /* "pywrapfst.pyx":3347
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -35333,11 +35460,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3334, __pyx_L1_error)
+    __PYX_ERR(0, 3347, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3325
+  /* "pywrapfst.pyx":3338
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -35353,15 +35480,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_17seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_20seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_19seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_20seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
@@ -35370,22 +35497,22 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3325, __pyx_L3_error)
+    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3338, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_17seek(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_19seek(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_19seek(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, size_t __pyx_v_a) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35394,7 +35521,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3325, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3338, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35403,7 +35530,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.seek", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35411,7 +35538,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3336
+/* "pywrapfst.pyx":3349
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35419,8 +35546,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
  *     set_flags(self, flags, mask)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_22set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -35443,12 +35570,12 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3336, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3349, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3336, __pyx_L1_error)
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_22set_flags)) {
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3349, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3336, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3349, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -35466,7 +35593,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3336, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3349, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -35476,7 +35603,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3336, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3349, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -35484,7 +35611,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3336, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3349, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -35495,7 +35622,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
           PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3336, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3349, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -35517,7 +35644,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3346
+  /* "pywrapfst.pyx":3359
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -35526,11 +35653,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3346, __pyx_L1_error)
+    __PYX_ERR(0, 3359, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3336
+  /* "pywrapfst.pyx":3349
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35548,15 +35675,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_19set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_22set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_21set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_22set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint8 __pyx_v_flags;
   uint8 __pyx_v_mask;
   int __pyx_lineno = 0;
@@ -35588,11 +35715,11 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3336, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3349, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3336, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3349, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -35600,25 +35727,25 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3336, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3336, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3349, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3349, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3336, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3349, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_21set_flags(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_21set_flags(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35627,7 +35754,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3336, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3349, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35636,7 +35763,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35644,7 +35771,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3348
+/* "pywrapfst.pyx":3361
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35652,8 +35779,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
  *     set_value(self, arc)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_24set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -35672,9 +35799,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3348, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3361, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_24set_value)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -35688,7 +35815,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_arc)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_arc));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3348, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3361, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35708,7 +35835,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3357
+  /* "pywrapfst.pyx":3370
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -35717,15 +35844,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3357, __pyx_L1_error)
+    __PYX_ERR(0, 3370, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3357, __pyx_L1_error)
+    __PYX_ERR(0, 3370, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3348
+  /* "pywrapfst.pyx":3361
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35740,23 +35867,23 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.MutableArcIterator.set_value", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._MutableArcIterator.set_value", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_21set_value[] = "\n    set_value(self, arc)\n\n    Replace the current arc with a new arc.\n\n    Args:\n      arc: The arc to replace the current arc with.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_24set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_23set_value[] = "\n    set_value(self, arc)\n\n    Replace the current arc with a new arc.\n\n    Args:\n      arc: The arc to replace the current arc with.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_24set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc) {
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_value (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3348, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3361, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_23set_value(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
 
   /* function exit code */
   goto __pyx_L0;
@@ -35767,7 +35894,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_23set_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35776,7 +35903,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_value(__pyx_v_self, __pyx_v_arc, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3348, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableArcIterator_set_value(__pyx_v_self, __pyx_v_arc, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3361, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35785,7 +35912,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.set_value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35793,7 +35920,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3359
+/* "pywrapfst.pyx":3372
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35801,8 +35928,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
  *     value(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_24value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_26value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_19_MutableArcIterator_value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35822,9 +35949,9 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3359, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3372, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_24value)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableArcIterator_26value)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -35839,7 +35966,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3359, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3372, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -35860,7 +35987,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3365
+  /* "pywrapfst.pyx":3378
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -35870,15 +35997,15 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3365, __pyx_L1_error)
+    __PYX_ERR(0, 3378, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3365, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3378, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3359
+  /* "pywrapfst.pyx":3372
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35892,7 +36019,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35901,20 +36028,20 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_24value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_23value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_24value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_26value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableArcIterator_25value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_26value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("value (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_23value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_25value(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_25value(struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35923,7 +36050,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3359, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_19_MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3372, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35932,7 +36059,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -35947,19 +36074,19 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_26__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_26__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_28__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_28__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_27__reduce_cython__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_27__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -35989,7 +36116,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CY
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
@@ -36004,19 +36131,19 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CY
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_28__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_28__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_30__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_MutableArcIterator_30__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableArcIterator_29__setstate_cython__(((struct __pyx_obj_9pywrapfst__MutableArcIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableArcIterator_29__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36046,35 +36173,35 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableArcIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3379
+/* "pywrapfst.pyx":3392
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<StateIterator at 0x{id(self):x}>"
+ *     return f"<_StateIterator at 0x{id(self):x}>"
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator___repr__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator___repr__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator___repr__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36087,25 +36214,25 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3380
+  /* "pywrapfst.pyx":3393
  * 
  *   def __repr__(self):
- *     return f"<StateIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
+ *     return f"<_StateIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, Fst ifst):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3380, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
   __Pyx_INCREF(__pyx_kp_u_StateIterator_at_0x);
-  __pyx_t_2 += 20;
+  __pyx_t_2 += 21;
   __Pyx_GIVEREF(__pyx_kp_u_StateIterator_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_StateIterator_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3380, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3380, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -36117,18 +36244,18 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3380, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3379
+  /* "pywrapfst.pyx":3392
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return f"<StateIterator at 0x{id(self):x}>"
+ *     return f"<_StateIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -36137,7 +36264,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -36145,8 +36272,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3382
- *     return f"<StateIterator at 0x{id(self):x}>"
+/* "pywrapfst.pyx":3395
+ *     return f"<_StateIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -36154,8 +36281,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static int __pyx_pw_9pywrapfst_14_StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_9pywrapfst_14_StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
@@ -36182,7 +36309,7 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3382, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3395, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -36193,14 +36320,14 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3382, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3395, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3382, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_2__init__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self), __pyx_v_ifst);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3395, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_2__init__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self), __pyx_v_ifst);
 
   /* function exit code */
   goto __pyx_L0;
@@ -36211,7 +36338,7 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst) {
+static int __pyx_pf_9pywrapfst_14_StateIterator_2__init__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::shared_ptr<fst::script::FstClass>  __pyx_t_1;
@@ -36220,7 +36347,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3384
+  /* "pywrapfst.pyx":3397
  *   def __init__(self, Fst ifst):
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -36229,16 +36356,16 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3384, __pyx_L1_error)
+    __PYX_ERR(0, 3397, __pyx_L1_error)
   }
   __pyx_t_1 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3384, __pyx_L1_error)
+    __PYX_ERR(0, 3397, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3385
+  /* "pywrapfst.pyx":3398
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  *     self._siter.reset(new fst.StateIteratorClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -36247,16 +36374,16 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3385, __pyx_L1_error)
+    __PYX_ERR(0, 3398, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3385, __pyx_L1_error)
+    __PYX_ERR(0, 3398, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3382
- *     return f"<StateIterator at 0x{id(self):x}>"
+  /* "pywrapfst.pyx":3395
+ *     return f"<_StateIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -36267,14 +36394,14 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3388
+/* "pywrapfst.pyx":3401
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -36283,24 +36410,24 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_5__iter__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_5__iter__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_4__iter__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_4__iter__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_4__iter__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3389
+  /* "pywrapfst.pyx":3402
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -36312,7 +36439,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3388
+  /* "pywrapfst.pyx":3401
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -36327,7 +36454,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3392
+/* "pywrapfst.pyx":3405
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -36336,19 +36463,19 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_7__next__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_7__next__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_6__next__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_6__next__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_6__next__(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   int64 __pyx_v_result;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -36359,7 +36486,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3393
+  /* "pywrapfst.pyx":3406
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -36368,12 +36495,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3393, __pyx_L1_error)
+    __PYX_ERR(0, 3406, __pyx_L1_error)
   }
-  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
+  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst__StateIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3394
+    /* "pywrapfst.pyx":3407
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -36381,9 +36508,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  *     self.next()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 3394, __pyx_L1_error)
+    __PYX_ERR(0, 3407, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3393
+    /* "pywrapfst.pyx":3406
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -36392,7 +36519,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3395
+  /* "pywrapfst.pyx":3408
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -36401,11 +36528,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3395, __pyx_L1_error)
+    __PYX_ERR(0, 3408, __pyx_L1_error)
   }
-  __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
+  __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst__StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3396
+  /* "pywrapfst.pyx":3409
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -36414,11 +36541,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3396, __pyx_L1_error)
+    __PYX_ERR(0, 3409, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
+  ((struct __pyx_vtabstruct_9pywrapfst__StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3397
+  /* "pywrapfst.pyx":3410
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -36426,13 +36553,13 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  *   cpdef bool done(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3397, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3410, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3392
+  /* "pywrapfst.pyx":3405
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -36443,7 +36570,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -36451,7 +36578,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3399
+/* "pywrapfst.pyx":3412
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36459,8 +36586,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  *     done(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static bool __pyx_f_9pywrapfst_14_StateIterator_done(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36481,9 +36608,9 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3399, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3412, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_9done)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_14_StateIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -36497,10 +36624,10 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3399, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3412, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3399, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3412, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36519,7 +36646,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3408
+  /* "pywrapfst.pyx":3421
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -36528,12 +36655,12 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3408, __pyx_L1_error)
+    __PYX_ERR(0, 3421, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3399
+  /* "pywrapfst.pyx":3412
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36547,7 +36674,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.StateIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._StateIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -36555,20 +36682,20 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_14_StateIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("done (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_8done(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_8done(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_8done(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36577,7 +36704,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_13StateIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3399, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_14_StateIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3412, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36586,7 +36713,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -36594,7 +36721,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3410
+/* "pywrapfst.pyx":3423
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36602,8 +36729,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
  *     next(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_14_StateIterator_next(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -36622,9 +36749,9 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3410, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3423, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_11next)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_14_StateIterator_11next)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -36638,7 +36765,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3410, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3423, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -36658,7 +36785,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3416
+  /* "pywrapfst.pyx":3429
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -36667,11 +36794,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3416, __pyx_L1_error)
+    __PYX_ERR(0, 3429, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3410
+  /* "pywrapfst.pyx":3423
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36686,26 +36813,26 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.StateIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._StateIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_14_StateIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("next (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_10next(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_10next(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_10next(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36714,7 +36841,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3410, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_14_StateIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36723,7 +36850,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -36731,7 +36858,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3418
+/* "pywrapfst.pyx":3431
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36739,8 +36866,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
  *     reset(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static void __pyx_f_9pywrapfst_14_StateIterator_reset(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -36759,9 +36886,9 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3418, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3431, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_13reset)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_14_StateIterator_13reset)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -36775,7 +36902,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3418, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3431, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -36795,7 +36922,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":3424
+  /* "pywrapfst.pyx":3437
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -36804,11 +36931,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3424, __pyx_L1_error)
+    __PYX_ERR(0, 3437, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3418
+  /* "pywrapfst.pyx":3431
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36823,26 +36950,26 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.StateIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._StateIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_14_StateIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reset (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_12reset(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_12reset(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_12reset(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36851,7 +36978,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3418, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_14_StateIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3431, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36860,7 +36987,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -36868,7 +36995,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3426
+/* "pywrapfst.pyx":3439
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36876,8 +37003,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
  *     value(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static int64 __pyx_f_9pywrapfst_14_StateIterator_value(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36898,9 +37025,9 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3426, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3439, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_15value)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_14_StateIterator_15value)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -36914,10 +37041,10 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3426, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3439, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3426, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3439, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36936,7 +37063,7 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
     #endif
   }
 
-  /* "pywrapfst.pyx":3432
+  /* "pywrapfst.pyx":3445
  *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -36945,12 +37072,12 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3432, __pyx_L1_error)
+    __PYX_ERR(0, 3445, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3426
+  /* "pywrapfst.pyx":3439
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36964,7 +37091,7 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.StateIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst._StateIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -36972,20 +37099,20 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_14value[] = "\n    value(self)\n\n    Returns the current state index.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_14_StateIterator_14value[] = "\n    value(self)\n\n    Returns the current state index.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("value (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_14value(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_14value(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_14value(struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -36994,7 +37121,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_13StateIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3426, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_14_StateIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3439, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37003,7 +37130,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -37018,19 +37145,19 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_17__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_17__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_17__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_17__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_16__reduce_cython__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37060,7 +37187,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
@@ -37075,19 +37202,19 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_19__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_13StateIterator_19__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_19__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_14_StateIterator_19__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __pyx_r = __pyx_pf_9pywrapfst_14_StateIterator_18__setstate_cython__(((struct __pyx_obj_9pywrapfst__StateIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_14_StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37117,14 +37244,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.StateIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._StateIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3438
+/* "pywrapfst.pyx":3451
  * 
  * 
  * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
@@ -37137,7 +37264,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_u_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3442
+  /* "pywrapfst.pyx":3455
  *                map_type="identity",
  *                double power=1.,
  *                weight=None):             # <<<<<<<<<<<<<<
@@ -37145,7 +37272,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
  *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  enum fst::script::MapType __pyx_v__map_type;
+  fst::script::MapType __pyx_v__map_type;
   fst::script::WeightClass __pyx_v__weight;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -37175,29 +37302,29 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
     }
   }
 
-  /* "pywrapfst.pyx":3444
+  /* "pywrapfst.pyx":3457
  *                weight=None):
  *   cdef fst.MapType _map_type
  *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):             # <<<<<<<<<<<<<<
  *     raise FstArgError(f"Unknown map type: {map_type!r}")
  *   cdef fst.WeightClass _weight
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3444, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3457, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v__map_type)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3445
+    /* "pywrapfst.pyx":3458
  *   cdef fst.MapType _map_type
  *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):
  *     raise FstArgError(f"Unknown map type: {map_type!r}")             # <<<<<<<<<<<<<<
  *   cdef fst.WeightClass _weight
- *   if _map_type == fst.TIMES_MAPPER:
+ *   if _map_type == fst.MapType.TIMES_MAPPER:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3445, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3458, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_map_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3445, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_map_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3458, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_map_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3445, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_map_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3458, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -37213,14 +37340,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3445, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3458, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3445, __pyx_L1_error)
+    __PYX_ERR(0, 3458, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3444
+    /* "pywrapfst.pyx":3457
  *                weight=None):
  *   cdef fst.MapType _map_type
  *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):             # <<<<<<<<<<<<<<
@@ -37229,76 +37356,92 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
  */
   }
 
-  /* "pywrapfst.pyx":3447
+  /* "pywrapfst.pyx":3460
  *     raise FstArgError(f"Unknown map type: {map_type!r}")
  *   cdef fst.WeightClass _weight
- *   if _map_type == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *   if _map_type == fst.MapType.TIMES_MAPPER:             # <<<<<<<<<<<<<<
  *       _weight = _get_WeightClass_or_one(ifst.weight_type(), weight)
  *   else:
  */
-  __pyx_t_2 = ((__pyx_v__map_type == fst::script::TIMES_MAPPER) != 0);
+  __pyx_t_2 = ((__pyx_v__map_type == fst::script::MapType::TIMES) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3448
+    /* "pywrapfst.pyx":3461
  *   cdef fst.WeightClass _weight
- *   if _map_type == fst.TIMES_MAPPER:
+ *   if _map_type == fst.MapType.TIMES_MAPPER:
  *       _weight = _get_WeightClass_or_one(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
  *   else:
  *       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3448, __pyx_L1_error)
+      __PYX_ERR(0, 3461, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_one(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3448, __pyx_L1_error)
+    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_one(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3461, __pyx_L1_error)
     __pyx_v__weight = __pyx_t_7;
 
-    /* "pywrapfst.pyx":3447
+    /* "pywrapfst.pyx":3460
  *     raise FstArgError(f"Unknown map type: {map_type!r}")
  *   cdef fst.WeightClass _weight
- *   if _map_type == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *   if _map_type == fst.MapType.TIMES_MAPPER:             # <<<<<<<<<<<<<<
  *       _weight = _get_WeightClass_or_one(ifst.weight_type(), weight)
  *   else:
  */
     goto __pyx_L4;
   }
 
-  /* "pywrapfst.pyx":3450
+  /* "pywrapfst.pyx":3463
  *       _weight = _get_WeightClass_or_one(ifst.weight_type(), weight)
  *   else:
  *       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
- *   return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))
- * 
+ *   return _init_XFst(
+ *     fst.Map(deref(ifst._fst), _map_type, delta, power, _weight).release())
  */
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3450, __pyx_L1_error)
+      __PYX_ERR(0, 3463, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3450, __pyx_L1_error)
+    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3463, __pyx_L1_error)
     __pyx_v__weight = __pyx_t_7;
   }
   __pyx_L4:;
 
-  /* "pywrapfst.pyx":3451
+  /* "pywrapfst.pyx":3464
  *   else:
  *       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)
- *   return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))             # <<<<<<<<<<<<<<
- * 
+ *   return _init_XFst(             # <<<<<<<<<<<<<<
+ *     fst.Map(deref(ifst._fst), _map_type, delta, power, _weight).release())
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+  /* "pywrapfst.pyx":3465
+ *       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)
+ *   return _init_XFst(
+ *     fst.Map(deref(ifst._fst), _map_type, delta, power, _weight).release())             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3451, __pyx_L1_error)
+    __PYX_ERR(0, 3465, __pyx_L1_error)
   }
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v__map_type, __pyx_v_delta, __pyx_v_power, __pyx_v__weight))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3451, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":3464
+ *   else:
+ *       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)
+ *   return _init_XFst(             # <<<<<<<<<<<<<<
+ *     fst.Map(deref(ifst._fst), _map_type, delta, power, _weight).release())
+ * 
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v__map_type, __pyx_v_delta, __pyx_v_power, __pyx_v__weight).release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3464, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3438
+  /* "pywrapfst.pyx":3451
  * 
  * 
  * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
@@ -37320,7 +37463,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3454
+/* "pywrapfst.pyx":3468
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
@@ -37334,7 +37477,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_u_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3458
+  /* "pywrapfst.pyx":3472
  *                  map_type="identity",
  *                  double power=1.,
  *                  weight=None):             # <<<<<<<<<<<<<<
@@ -37365,7 +37508,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
     }
   }
 
-  /* "pywrapfst.pyx":3498
+  /* "pywrapfst.pyx":3512
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, delta, map_type, power, weight)             # <<<<<<<<<<<<<<
@@ -37378,13 +37521,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3498, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3512, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3454
+  /* "pywrapfst.pyx":3468
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
@@ -37423,7 +37566,7 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
     PyObject* values[5] = {0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_u_identity);
 
-    /* "pywrapfst.pyx":3458
+    /* "pywrapfst.pyx":3472
  *                  map_type="identity",
  *                  double power=1.,
  *                  weight=None):             # <<<<<<<<<<<<<<
@@ -37479,7 +37622,7 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3454, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3468, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37498,13 +37641,13 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3455, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3469, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__33;
     }
     __pyx_v_map_type = values[2];
     if (values[3]) {
-      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3457, __pyx_L3_error)
+      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3471, __pyx_L3_error)
     } else {
       __pyx_v_power = ((double)1.);
     }
@@ -37512,16 +37655,16 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3454, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3468, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.arcmap", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3454, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3468, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_20arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_power, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3454
+  /* "pywrapfst.pyx":3468
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
@@ -37553,7 +37696,7 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_arcmap(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3454, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_arcmap(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37570,7 +37713,7 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3501
+/* "pywrapfst.pyx":3515
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37582,7 +37725,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args) {
   PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3504
+  /* "pywrapfst.pyx":3518
  *                          Fst ifst2,
  *                          compose_filter="auto",
  *                          bool connect=True):             # <<<<<<<<<<<<<<
@@ -37610,7 +37753,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
     }
   }
 
-  /* "pywrapfst.pyx":3528
+  /* "pywrapfst.pyx":3542
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -37619,21 +37762,21 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3528, __pyx_L1_error)
+    __PYX_ERR(0, 3542, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3532
+  /* "pywrapfst.pyx":3546
  *   _opts.reset(
  *       new fst.ComposeOptions(connect,
  *                              _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3532, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3532, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3546, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3546, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3530
+  /* "pywrapfst.pyx":3544
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -37642,7 +37785,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
  */
   __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3533
+  /* "pywrapfst.pyx":3547
  *       new fst.ComposeOptions(connect,
  *                              _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -37651,15 +37794,15 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3533, __pyx_L1_error)
+    __PYX_ERR(0, 3547, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3533, __pyx_L1_error)
+    __PYX_ERR(0, 3547, __pyx_L1_error)
   }
   fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3534
+  /* "pywrapfst.pyx":3548
  *                              _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -37667,13 +37810,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3534, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3548, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3501
+  /* "pywrapfst.pyx":3515
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37734,7 +37877,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3501, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3515, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37750,7 +37893,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3501, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3515, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37768,10 +37911,10 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3504, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3518, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3504
+      /* "pywrapfst.pyx":3518
  *                          Fst ifst2,
  *                          compose_filter="auto",
  *                          bool connect=True):             # <<<<<<<<<<<<<<
@@ -37783,17 +37926,17 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3501, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3515, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.compose", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3501, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3502, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3515, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3516, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_22compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3501
+  /* "pywrapfst.pyx":3515
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37823,7 +37966,7 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compose(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3501, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compose(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3515, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37840,7 +37983,7 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3537
+/* "pywrapfst.pyx":3551
  * 
  * 
  * cpdef Fst convert(Fst ifst, fst_type=""):             # <<<<<<<<<<<<<<
@@ -37873,31 +38016,31 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3554
+  /* "pywrapfst.pyx":3568
  *     FstOpError: Conversion failed.
  *   """
  *   cdef string _fst_type = tostring(fst_type)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] _tfst
- *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
+ *   _tfst = fst.Convert(deref(ifst._fst), _fst_type)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3554, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3568, __pyx_L1_error)
   __pyx_v__fst_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3556
+  /* "pywrapfst.pyx":3570
  *   cdef string _fst_type = tostring(fst_type)
  *   cdef unique_ptr[fst.FstClass] _tfst
- *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))             # <<<<<<<<<<<<<<
+ *   _tfst = fst.Convert(deref(ifst._fst), _fst_type)             # <<<<<<<<<<<<<<
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if _tfst.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3556, __pyx_L1_error)
+    __PYX_ERR(0, 3570, __pyx_L1_error)
   }
-  __pyx_v__tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v__fst_type));
+  __pyx_v__tfst = fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v__fst_type);
 
-  /* "pywrapfst.pyx":3558
- *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
+  /* "pywrapfst.pyx":3572
+ *   _tfst = fst.Convert(deref(ifst._fst), _fst_type)
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *     raise FstOpError(f"Conversion to {fst_type!r} failed")
@@ -37906,16 +38049,16 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
   __pyx_t_2 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3559
+    /* "pywrapfst.pyx":3573
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if _tfst.get() == NULL:
  *     raise FstOpError(f"Conversion to {fst_type!r} failed")             # <<<<<<<<<<<<<<
  *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3559, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3573, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3559, __pyx_L1_error)
+    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3573, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = 0;
     __pyx_t_7 = 127;
@@ -37923,7 +38066,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
     __pyx_t_6 += 14;
     __Pyx_GIVEREF(__pyx_kp_u_Conversion_to);
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Conversion_to);
-    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_fst_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3559, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_fst_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3573, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
     __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7;
     __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
@@ -37934,7 +38077,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
     __pyx_t_6 += 7;
     __Pyx_GIVEREF(__pyx_kp_u_failed);
     PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_failed);
-    __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_5, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3559, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_5, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3573, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -37950,15 +38093,15 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_8) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_8);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3559, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3573, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3559, __pyx_L1_error)
+    __PYX_ERR(0, 3573, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3558
- *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
+    /* "pywrapfst.pyx":3572
+ *   _tfst = fst.Convert(deref(ifst._fst), _fst_type)
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *     raise FstOpError(f"Conversion to {fst_type!r} failed")
@@ -37966,7 +38109,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
  */
   }
 
-  /* "pywrapfst.pyx":3560
+  /* "pywrapfst.pyx":3574
  *   if _tfst.get() == NULL:
  *     raise FstOpError(f"Conversion to {fst_type!r} failed")
  *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -37974,13 +38117,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3560, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3574, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3537
+  /* "pywrapfst.pyx":3551
  * 
  * 
  * cpdef Fst convert(Fst ifst, fst_type=""):             # <<<<<<<<<<<<<<
@@ -38042,7 +38185,7 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3537, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3551, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38058,13 +38201,13 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3537, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3551, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.convert", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3537, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3551, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_24convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
@@ -38088,7 +38231,7 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.fst_type = __pyx_v_fst_type;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_convert(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3537, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_convert(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3551, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38105,7 +38248,7 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3563
+/* "pywrapfst.pyx":3577
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38120,7 +38263,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
   int64 __pyx_v_nstate = __pyx_k__35;
   int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3568
+  /* "pywrapfst.pyx":3582
  *                              int64 nstate=fst.kNoStateId,
  *                              int64 subsequential_label=0,
  *                              weight=None,             # <<<<<<<<<<<<<<
@@ -38129,7 +38272,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3569
+  /* "pywrapfst.pyx":3583
  *                              int64 subsequential_label=0,
  *                              weight=None,
  *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -38175,7 +38318,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
     }
   }
 
-  /* "pywrapfst.pyx":3603
+  /* "pywrapfst.pyx":3617
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38184,11 +38327,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3603, __pyx_L1_error)
+    __PYX_ERR(0, 3617, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3605
+  /* "pywrapfst.pyx":3619
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -38197,42 +38340,42 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3605, __pyx_L1_error)
+    __PYX_ERR(0, 3619, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3606
+  /* "pywrapfst.pyx":3620
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),
  *                                                           weight)             # <<<<<<<<<<<<<<
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3605, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3619, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3608
+  /* "pywrapfst.pyx":3622
  *                                                           weight)
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):             # <<<<<<<<<<<<<<
  *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
  *   cdef unique_ptr[fst.DeterminizeOptions] _opts
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3608, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3622, __pyx_L1_error)
   __pyx_t_3 = ((!(fst::script::GetDeterminizeType(__pyx_t_2, (&__pyx_v__det_type)) != 0)) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":3609
+    /* "pywrapfst.pyx":3623
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):
  *     raise FstArgError(f"Unknown determinization type: {det_type!r}")             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.DeterminizeOptions] _opts
  *   _opts.reset(
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3609, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3623, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_det_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3609, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_det_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3623, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3609, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3623, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -38248,14 +38391,14 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
     __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3609, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3623, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 3609, __pyx_L1_error)
+    __PYX_ERR(0, 3623, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3608
+    /* "pywrapfst.pyx":3622
  *                                                           weight)
  *   cdef fst.DeterminizeType _det_type
  *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):             # <<<<<<<<<<<<<<
@@ -38264,7 +38407,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   }
 
-  /* "pywrapfst.pyx":3611
+  /* "pywrapfst.pyx":3625
  *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
  *   cdef unique_ptr[fst.DeterminizeOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -38273,7 +38416,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   __pyx_v__opts.reset(new fst::script::DeterminizeOptions(__pyx_v_delta, __pyx_v__weight, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v__det_type, __pyx_v_increment_subsequential_label));
 
-  /* "pywrapfst.pyx":3618
+  /* "pywrapfst.pyx":3632
  *                                  _det_type,
  *                                  increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -38282,11 +38425,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3618, __pyx_L1_error)
+    __PYX_ERR(0, 3632, __pyx_L1_error)
   }
   fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3619
+  /* "pywrapfst.pyx":3633
  *                                  increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -38294,13 +38437,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3619, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3633, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3563
+  /* "pywrapfst.pyx":3577
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38344,7 +38487,7 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_u_functional);
 
-    /* "pywrapfst.pyx":3568
+    /* "pywrapfst.pyx":3582
  *                              int64 nstate=fst.kNoStateId,
  *                              int64 subsequential_label=0,
  *                              weight=None,             # <<<<<<<<<<<<<<
@@ -38416,7 +38559,7 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3563, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3577, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38439,27 +38582,27 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3564, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3578, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__34;
     }
     __pyx_v_det_type = values[2];
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3566, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3580, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__35;
     }
     if (values[4]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3567, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3581, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((int64)0);
     }
     __pyx_v_weight = values[5];
     if (values[6]) {
-      __pyx_v_increment_subsequential_label = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_increment_subsequential_label == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3569, __pyx_L3_error)
+      __pyx_v_increment_subsequential_label = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_increment_subsequential_label == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3583, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3569
+      /* "pywrapfst.pyx":3583
  *                              int64 subsequential_label=0,
  *                              weight=None,
  *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -38471,16 +38614,16 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3563, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3577, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.determinize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3563, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3577, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_26determinize(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_det_type, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight, __pyx_v_increment_subsequential_label);
 
-  /* "pywrapfst.pyx":3563
+  /* "pywrapfst.pyx":3577
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38514,7 +38657,7 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
   __pyx_t_2.increment_subsequential_label = __pyx_v_increment_subsequential_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_determinize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3563, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_determinize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3577, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38531,7 +38674,7 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3622
+/* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38543,7 +38686,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args) {
   PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3625
+  /* "pywrapfst.pyx":3639
  *                             Fst ifst2,
  *                             compose_filter="auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38571,7 +38714,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
     }
   }
 
-  /* "pywrapfst.pyx":3650
+  /* "pywrapfst.pyx":3664
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -38580,21 +38723,21 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3650, __pyx_L1_error)
+    __PYX_ERR(0, 3664, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3654
+  /* "pywrapfst.pyx":3668
  *   _opts.reset(
  *       new fst.ComposeOptions(connect,
  *                             _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Difference(deref(ifst1._fst),
  *                  deref(ifst2._fst),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3654, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3654, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3668, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3668, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3652
+  /* "pywrapfst.pyx":3666
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -38603,7 +38746,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  */
   __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3655
+  /* "pywrapfst.pyx":3669
  *       new fst.ComposeOptions(connect,
  *                             _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -38612,10 +38755,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3655, __pyx_L1_error)
+    __PYX_ERR(0, 3669, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3656
+  /* "pywrapfst.pyx":3670
  *                             _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst),
  *                  deref(ifst2._fst),             # <<<<<<<<<<<<<<
@@ -38624,10 +38767,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3656, __pyx_L1_error)
+    __PYX_ERR(0, 3670, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3655
+  /* "pywrapfst.pyx":3669
  *       new fst.ComposeOptions(connect,
  *                             _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -38636,7 +38779,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  */
   fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3659
+  /* "pywrapfst.pyx":3673
  *                  _tfst.get(),
  *                  deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -38644,13 +38787,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3659, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3673, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3622
+  /* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38711,7 +38854,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3622, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3636, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38727,7 +38870,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3622, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3636, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38745,10 +38888,10 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3625, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3639, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3625
+      /* "pywrapfst.pyx":3639
  *                             Fst ifst2,
  *                             compose_filter="auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38760,17 +38903,17 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3622, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3636, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.difference", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3622, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3623, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3636, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3637, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_28difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3622
+  /* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38800,7 +38943,7 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_difference(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3622, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_difference(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3636, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38817,7 +38960,7 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3662
+/* "pywrapfst.pyx":3676
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38831,7 +38974,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
   int64 __pyx_v_nstate = __pyx_k__37;
   int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3666
+  /* "pywrapfst.pyx":3680
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -38865,7 +39008,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
     }
   }
 
-  /* "pywrapfst.pyx":3691
+  /* "pywrapfst.pyx":3705
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38874,11 +39017,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3691, __pyx_L1_error)
+    __PYX_ERR(0, 3705, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3693
+  /* "pywrapfst.pyx":3707
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -38887,20 +39030,20 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3693, __pyx_L1_error)
+    __PYX_ERR(0, 3707, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3694
+  /* "pywrapfst.pyx":3708
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),
  *                                                      weight)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.DisambiguateOptions] _opts
  *   _opts.reset(
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3693, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3707, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3696
+  /* "pywrapfst.pyx":3710
  *                                                      weight)
  *   cdef unique_ptr[fst.DisambiguateOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -38909,7 +39052,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  */
   __pyx_v__opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v__weight, __pyx_v_nstate, __pyx_v_subsequential_label));
 
-  /* "pywrapfst.pyx":3701
+  /* "pywrapfst.pyx":3715
  *                                   nstate,
  *                                   subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -38918,11 +39061,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3701, __pyx_L1_error)
+    __PYX_ERR(0, 3715, __pyx_L1_error)
   }
   fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3702
+  /* "pywrapfst.pyx":3716
  *                                   subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -38930,13 +39073,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3702, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3716, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3662
+  /* "pywrapfst.pyx":3676
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38974,7 +39117,7 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_subsequential_label,&__pyx_n_s_weight,0};
     PyObject* values[5] = {0,0,0,0,0};
 
-    /* "pywrapfst.pyx":3666
+    /* "pywrapfst.pyx":3680
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -39030,7 +39173,7 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3662, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3676, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39049,17 +39192,17 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3663, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3677, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__36;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3664, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3678, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__37;
     }
     if (values[3]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3665, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3679, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((int64)0);
     }
@@ -39067,16 +39210,16 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3662, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3676, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.disambiguate", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3662, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3676, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_30disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3662
+  /* "pywrapfst.pyx":3676
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -39108,7 +39251,7 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_disambiguate(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3662, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_disambiguate(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3676, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39125,7 +39268,7 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3705
+/* "pywrapfst.pyx":3719
  * 
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -39151,7 +39294,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
     }
   }
 
-  /* "pywrapfst.pyx":3726
+  /* "pywrapfst.pyx":3740
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -39160,11 +39303,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3726, __pyx_L1_error)
+    __PYX_ERR(0, 3740, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3728
+  /* "pywrapfst.pyx":3742
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(
  *       deref(ifst._fst),             # <<<<<<<<<<<<<<
@@ -39173,10 +39316,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3728, __pyx_L1_error)
+    __PYX_ERR(0, 3742, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3730
+  /* "pywrapfst.pyx":3744
  *       deref(ifst._fst),
  *       _tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
@@ -39189,7 +39332,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3727
+  /* "pywrapfst.pyx":3741
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(             # <<<<<<<<<<<<<<
@@ -39198,7 +39341,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
  */
   fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_t_1);
 
-  /* "pywrapfst.pyx":3731
+  /* "pywrapfst.pyx":3745
  *       _tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -39206,13 +39349,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3731, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3745, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3705
+  /* "pywrapfst.pyx":3719
  * 
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -39270,7 +39413,7 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3705, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3719, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39283,20 +39426,20 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_eps_norm_output = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_eps_norm_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3705, __pyx_L3_error)
+      __pyx_v_eps_norm_output = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_eps_norm_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3719, __pyx_L3_error)
     } else {
       __pyx_v_eps_norm_output = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3705, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3719, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.epsnormalize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3705, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3719, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_32epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
@@ -39320,7 +39463,7 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.eps_norm_output = __pyx_v_eps_norm_output;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_epsnormalize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3705, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_epsnormalize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3719, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39337,7 +39480,7 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3734
+/* "pywrapfst.pyx":3748
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39360,7 +39503,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_if
     }
   }
 
-  /* "pywrapfst.pyx":3752
+  /* "pywrapfst.pyx":3766
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39369,16 +39512,16 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_if
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3752, __pyx_L1_error)
+    __PYX_ERR(0, 3766, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3752, __pyx_L1_error)
+    __PYX_ERR(0, 3766, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3734
+  /* "pywrapfst.pyx":3748
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39433,7 +39576,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3734, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3748, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39443,7 +39586,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3734, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3748, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39458,21 +39601,21 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3734, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3748, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__38;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3734, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3748, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.equal", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3734, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3734, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3748, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3748, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_34equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39498,7 +39641,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_equal(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3734, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39515,7 +39658,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3755
+/* "pywrapfst.pyx":3769
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39538,7 +39681,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx
     }
   }
 
-  /* "pywrapfst.pyx":3773
+  /* "pywrapfst.pyx":3787
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39547,16 +39690,16 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3773, __pyx_L1_error)
+    __PYX_ERR(0, 3787, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3773, __pyx_L1_error)
+    __PYX_ERR(0, 3787, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3755
+  /* "pywrapfst.pyx":3769
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39611,7 +39754,7 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3755, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3769, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39621,7 +39764,7 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3755, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3769, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39636,21 +39779,21 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3755, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3769, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__39;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3755, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3769, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.equivalent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3755, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3755, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3769, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3769, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_36equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39676,7 +39819,7 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3755, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3769, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39693,7 +39836,7 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3776
+/* "pywrapfst.pyx":3790
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39705,7 +39848,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args) {
   PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3779
+  /* "pywrapfst.pyx":3793
  *                            Fst ifst2,
  *                            compose_filter="auto",
  *                            bool connect=True):             # <<<<<<<<<<<<<<
@@ -39733,7 +39876,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
     }
   }
 
-  /* "pywrapfst.pyx":3802
+  /* "pywrapfst.pyx":3816
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -39742,21 +39885,21 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3802, __pyx_L1_error)
+    __PYX_ERR(0, 3816, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3806
+  /* "pywrapfst.pyx":3820
  *   _opts.reset(
  *       new fst.ComposeOptions(connect,
  *                             _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3806, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3806, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3820, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3820, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3804
+  /* "pywrapfst.pyx":3818
  *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -39765,7 +39908,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
  */
   __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3807
+  /* "pywrapfst.pyx":3821
  *       new fst.ComposeOptions(connect,
  *                             _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -39774,15 +39917,15 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3807, __pyx_L1_error)
+    __PYX_ERR(0, 3821, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3807, __pyx_L1_error)
+    __PYX_ERR(0, 3821, __pyx_L1_error)
   }
   fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3808
+  /* "pywrapfst.pyx":3822
  *                             _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -39790,13 +39933,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3808, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3822, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3776
+  /* "pywrapfst.pyx":3790
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39857,7 +40000,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3776, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3790, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39873,7 +40016,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3776, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3790, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39891,10 +40034,10 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3779, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3793, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3779
+      /* "pywrapfst.pyx":3793
  *                            Fst ifst2,
  *                            compose_filter="auto",
  *                            bool connect=True):             # <<<<<<<<<<<<<<
@@ -39906,17 +40049,17 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3776, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3790, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.intersect", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3776, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3777, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3790, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3791, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_38intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3776
+  /* "pywrapfst.pyx":3790
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39946,7 +40089,7 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_intersect(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3776, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_intersect(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3790, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39963,7 +40106,7 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3811
+/* "pywrapfst.pyx":3825
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39986,7 +40129,7 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *__pyx
     }
   }
 
-  /* "pywrapfst.pyx":3832
+  /* "pywrapfst.pyx":3846
  *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39995,16 +40138,16 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3832, __pyx_L1_error)
+    __PYX_ERR(0, 3846, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3832, __pyx_L1_error)
+    __PYX_ERR(0, 3846, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3811
+  /* "pywrapfst.pyx":3825
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -40059,7 +40202,7 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3811, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3825, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -40069,7 +40212,7 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3811, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3825, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40084,21 +40227,21 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3811, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3825, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__40;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3811, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3825, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.isomorphic", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3811, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3811, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3825, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3825, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_40isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -40124,7 +40267,7 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_isomorphic(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3811, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3825, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -40141,7 +40284,7 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3835
+/* "pywrapfst.pyx":3849
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40154,7 +40297,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
   float __pyx_v_delta = __pyx_k__41;
   int64 __pyx_v_nstate = __pyx_k__42;
 
-  /* "pywrapfst.pyx":3838
+  /* "pywrapfst.pyx":3852
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):             # <<<<<<<<<<<<<<
@@ -40184,7 +40327,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3860
+  /* "pywrapfst.pyx":3874
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40193,11 +40336,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3860, __pyx_L1_error)
+    __PYX_ERR(0, 3874, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3861
+  /* "pywrapfst.pyx":3875
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -40206,20 +40349,20 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3861, __pyx_L1_error)
+    __PYX_ERR(0, 3875, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3862
+  /* "pywrapfst.pyx":3876
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),
  *                                                           weight)             # <<<<<<<<<<<<<<
  *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
  *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3861, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3875, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3863
+  /* "pywrapfst.pyx":3877
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),
  *                                                           weight)
  *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -40228,11 +40371,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3863, __pyx_L1_error)
+    __PYX_ERR(0, 3877, __pyx_L1_error)
   }
   fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3864
+  /* "pywrapfst.pyx":3878
  *                                                           weight)
  *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -40240,13 +40383,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3864, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3878, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3835
+  /* "pywrapfst.pyx":3849
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40283,7 +40426,7 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[4] = {0,0,0,0};
 
-    /* "pywrapfst.pyx":3838
+    /* "pywrapfst.pyx":3852
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):             # <<<<<<<<<<<<<<
@@ -40331,7 +40474,7 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3835, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3849, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40348,12 +40491,12 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3836, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3850, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__41;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3837, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3851, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__42;
     }
@@ -40361,16 +40504,16 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3835, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3849, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3835, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3849, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_42prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3835
+  /* "pywrapfst.pyx":3849
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40401,7 +40544,7 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_prune(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3835, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_prune(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3849, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40418,7 +40561,7 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3867
+/* "pywrapfst.pyx":3881
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40430,7 +40573,7 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args) {
   float __pyx_v_delta = __pyx_k__43;
 
-  /* "pywrapfst.pyx":3869
+  /* "pywrapfst.pyx":3883
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -40439,7 +40582,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3870
+  /* "pywrapfst.pyx":3884
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,
  *                       bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -40448,7 +40591,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3871
+  /* "pywrapfst.pyx":3885
  *                       bool push_weights=False,
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -40457,7 +40600,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3872
+  /* "pywrapfst.pyx":3886
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -40466,7 +40609,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3873
+  /* "pywrapfst.pyx":3887
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,
  *                       bool to_final=False):             # <<<<<<<<<<<<<<
@@ -40504,7 +40647,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
     }
   }
 
-  /* "pywrapfst.pyx":3910
+  /* "pywrapfst.pyx":3924
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40513,11 +40656,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3910, __pyx_L1_error)
+    __PYX_ERR(0, 3924, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3911
+  /* "pywrapfst.pyx":3925
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef uint8 flags = fst.GetPushFlags(push_weights,             # <<<<<<<<<<<<<<
@@ -40526,7 +40669,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   __pyx_v_flags = fst::script::GetPushFlags(__pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight);
 
-  /* "pywrapfst.pyx":3915
+  /* "pywrapfst.pyx":3929
  *                                       remove_common_affix,
  *                                       remove_total_weight)
  *   fst.Push(deref(ifst._fst),             # <<<<<<<<<<<<<<
@@ -40535,10 +40678,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3915, __pyx_L1_error)
+    __PYX_ERR(0, 3929, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3919
+  /* "pywrapfst.pyx":3933
  *            flags,
  *            fst.GetReweightType(to_final),
  *            delta)             # <<<<<<<<<<<<<<
@@ -40547,7 +40690,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   fst::script::Push((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v_flags, fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3920
+  /* "pywrapfst.pyx":3934
  *            fst.GetReweightType(to_final),
  *            delta)
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -40555,13 +40698,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3920, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3934, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3867
+  /* "pywrapfst.pyx":3881
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40664,7 +40807,7 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3867, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3881, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40687,15 +40830,15 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3868, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3882, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__43;
     }
     if (values[2]) {
-      __pyx_v_push_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_push_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3869, __pyx_L3_error)
+      __pyx_v_push_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_push_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3883, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3869
+      /* "pywrapfst.pyx":3883
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -40705,10 +40848,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_weights = ((bool)0);
     }
     if (values[3]) {
-      __pyx_v_push_labels = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_push_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3870, __pyx_L3_error)
+      __pyx_v_push_labels = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_push_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3884, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3870
+      /* "pywrapfst.pyx":3884
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,
  *                       bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -40718,10 +40861,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_labels = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_remove_common_affix = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_remove_common_affix == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3871, __pyx_L3_error)
+      __pyx_v_remove_common_affix = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_remove_common_affix == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3885, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3871
+      /* "pywrapfst.pyx":3885
  *                       bool push_weights=False,
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -40731,10 +40874,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_common_affix = ((bool)0);
     }
     if (values[5]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3872, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3886, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3872
+      /* "pywrapfst.pyx":3886
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -40744,10 +40887,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3873, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3887, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3873
+      /* "pywrapfst.pyx":3887
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,
  *                       bool to_final=False):             # <<<<<<<<<<<<<<
@@ -40759,16 +40902,16 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3867, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3881, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3867, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3881, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_44push(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":3867
+  /* "pywrapfst.pyx":3881
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40802,7 +40945,7 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.remove_common_affix = __pyx_v_remove_common_affix;
   __pyx_t_2.remove_total_weight = __pyx_v_remove_total_weight;
   __pyx_t_2.to_final = __pyx_v_to_final;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_push(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3867, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_push(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3881, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40819,7 +40962,7 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3923
+/* "pywrapfst.pyx":3937
  * 
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -40834,12 +40977,12 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
   PyObject *__pyx_v_select = ((PyObject *)__pyx_n_u_uniform);
   int32 __pyx_v_max_length = __pyx_k__45;
   uint64 __pyx_v_seed = ((uint64)0);
-  enum fst::script::RandArcSelection __pyx_v__select;
-  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v__opts;
+  fst::script::RandArcSelection __pyx_v__select;
+  std::unique_ptr<fst::RandGenOptions<fst::script::RandArcSelection> >  __pyx_v__opts;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
-  enum fst::script::RandArcSelection __pyx_t_2;
+  fst::script::RandArcSelection __pyx_t_2;
   int __pyx_t_3;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
@@ -40863,27 +41006,27 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
     }
   }
 
-  /* "pywrapfst.pyx":3956
+  /* "pywrapfst.pyx":3970
  *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   # The three trailing options will be ignored by RandEquivalent.
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3956, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3956, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3970, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3970, __pyx_L1_error)
   __pyx_v__select = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3959
+  /* "pywrapfst.pyx":3973
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   # The three trailing options will be ignored by RandEquivalent.
  *   _opts.reset(             # <<<<<<<<<<<<<<
  *        new fst.RandGenOptions[fst.RandArcSelection](_select,
  *                                                     max_length,
  */
-  __pyx_v__opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, 1, 0, 0));
+  __pyx_v__opts.reset(new fst::RandGenOptions<fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, 1, 0, 0));
 
-  /* "pywrapfst.pyx":3965
+  /* "pywrapfst.pyx":3979
  *                                                     False,
  *                                                     False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40893,7 +41036,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3966
+    /* "pywrapfst.pyx":3980
  *                                                     False))
  *   if seed == 0:
  *     seed = time(NULL)             # <<<<<<<<<<<<<<
@@ -40902,7 +41045,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
  */
     __pyx_v_seed = time(NULL);
 
-    /* "pywrapfst.pyx":3965
+    /* "pywrapfst.pyx":3979
  *                                                     False,
  *                                                     False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40911,7 +41054,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
  */
   }
 
-  /* "pywrapfst.pyx":3967
+  /* "pywrapfst.pyx":3981
  *   if seed == 0:
  *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -40920,10 +41063,10 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3967, __pyx_L1_error)
+    __PYX_ERR(0, 3981, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3968
+  /* "pywrapfst.pyx":3982
  *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),
  *                             deref(ifst2._fst),             # <<<<<<<<<<<<<<
@@ -40932,10 +41075,10 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
  */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3968, __pyx_L1_error)
+    __PYX_ERR(0, 3982, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3967
+  /* "pywrapfst.pyx":3981
  *   if seed == 0:
  *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -40945,7 +41088,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
   __pyx_r = fst::script::RandEquivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_npath, (*__pyx_v__opts), __pyx_v_delta, __pyx_v_seed);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3923
+  /* "pywrapfst.pyx":3937
  * 
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -41013,7 +41156,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3923, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3937, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -41047,7 +41190,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3923, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3937, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41070,37 +41213,37 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3925, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3939, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((int32)1);
     }
     if (values[3]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3926, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3940, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__44;
     }
     __pyx_v_select = values[4];
     if (values[5]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[5]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3928, __pyx_L3_error)
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[5]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3942, __pyx_L3_error)
     } else {
       __pyx_v_max_length = __pyx_k__45;
     }
     if (values[6]) {
-      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3929, __pyx_L3_error)
+      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3943, __pyx_L3_error)
     } else {
       __pyx_v_seed = ((uint64)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3923, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3937, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.randequivalent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3923, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3924, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3937, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3938, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_46randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_select, __pyx_v_max_length, __pyx_v_seed);
 
   /* function exit code */
@@ -41129,8 +41272,8 @@ static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__
   __pyx_t_2.select = __pyx_v_select;
   __pyx_t_2.max_length = __pyx_v_max_length;
   __pyx_t_2.seed = __pyx_v_seed;
-  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3923, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3923, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3937, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3937, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -41147,7 +41290,7 @@ static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3975
+/* "pywrapfst.pyx":3989
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
@@ -41161,7 +41304,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
   PyObject *__pyx_v_select = ((PyObject *)__pyx_n_u_uniform);
   int32 __pyx_v_max_length = __pyx_k__46;
 
-  /* "pywrapfst.pyx":3979
+  /* "pywrapfst.pyx":3993
  *                          select="uniform",
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,             # <<<<<<<<<<<<<<
@@ -41170,7 +41313,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":3994
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,
  *                          bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -41179,13 +41322,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
   uint64 __pyx_v_seed = ((uint64)0);
-  enum fst::script::RandArcSelection __pyx_v__select;
-  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v__opts;
+  fst::script::RandArcSelection __pyx_v__select;
+  std::unique_ptr<fst::RandGenOptions<fst::script::RandArcSelection> >  __pyx_v__opts;
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
-  enum fst::script::RandArcSelection __pyx_t_2;
+  fst::script::RandArcSelection __pyx_t_2;
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_lineno = 0;
@@ -41213,27 +41356,27 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
     }
   }
 
-  /* "pywrapfst.pyx":4011
+  /* "pywrapfst.pyx":4025
  *     An FST containing one or more random paths.
  *   """
  *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   _opts.reset(
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4011, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4011, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4025, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4025, __pyx_L1_error)
   __pyx_v__select = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4013
+  /* "pywrapfst.pyx":4027
  *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
  *       new fst.RandGenOptions[fst.RandArcSelection](_select,
  *                                                    max_length,
  */
-  __pyx_v__opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, __pyx_v_npath, __pyx_v_weighted, __pyx_v_remove_total_weight));
+  __pyx_v__opts.reset(new fst::RandGenOptions<fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, __pyx_v_npath, __pyx_v_weighted, __pyx_v_remove_total_weight));
 
-  /* "pywrapfst.pyx":4020
+  /* "pywrapfst.pyx":4034
  *                                                    remove_total_weight))
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -41242,11 +41385,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4020, __pyx_L1_error)
+    __PYX_ERR(0, 4034, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4021
+  /* "pywrapfst.pyx":4035
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -41256,7 +41399,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4022
+    /* "pywrapfst.pyx":4036
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:
  *     seed = time(NULL)             # <<<<<<<<<<<<<<
@@ -41265,7 +41408,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
     __pyx_v_seed = time(NULL);
 
-    /* "pywrapfst.pyx":4021
+    /* "pywrapfst.pyx":4035
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -41274,7 +41417,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
   }
 
-  /* "pywrapfst.pyx":4023
+  /* "pywrapfst.pyx":4037
  *   if seed == 0:
  *     seed = time(NULL)
  *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)             # <<<<<<<<<<<<<<
@@ -41283,11 +41426,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4023, __pyx_L1_error)
+    __PYX_ERR(0, 4037, __pyx_L1_error)
   }
   fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts), __pyx_v_seed);
 
-  /* "pywrapfst.pyx":4024
+  /* "pywrapfst.pyx":4038
  *     seed = time(NULL)
  *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -41295,13 +41438,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4024, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4038, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3975
+  /* "pywrapfst.pyx":3989
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
@@ -41405,7 +41548,7 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3975, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3989, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41428,21 +41571,21 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3976, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3990, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((int32)1);
     }
     __pyx_v_select = values[2];
     if (values[3]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[3]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3978, __pyx_L3_error)
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[3]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3992, __pyx_L3_error)
     } else {
       __pyx_v_max_length = __pyx_k__46;
     }
     if (values[4]) {
-      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3979, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3993, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3979
+      /* "pywrapfst.pyx":3993
  *                          select="uniform",
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,             # <<<<<<<<<<<<<<
@@ -41452,10 +41595,10 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
       __pyx_v_weighted = ((bool)0);
     }
     if (values[5]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3980, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3994, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3980
+      /* "pywrapfst.pyx":3994
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,
  *                          bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -41465,23 +41608,23 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3981, __pyx_L3_error)
+      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3995, __pyx_L3_error)
     } else {
       __pyx_v_seed = ((uint64)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3975, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3989, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.randgen", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3975, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3989, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_48randgen(__pyx_self, __pyx_v_ifst, __pyx_v_npath, __pyx_v_select, __pyx_v_max_length, __pyx_v_weighted, __pyx_v_remove_total_weight, __pyx_v_seed);
 
-  /* "pywrapfst.pyx":3975
+  /* "pywrapfst.pyx":3989
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
@@ -41515,7 +41658,7 @@ static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.remove_total_weight = __pyx_v_weighted;
   __pyx_t_2.weighted = __pyx_v_remove_total_weight;
   __pyx_t_2.seed = __pyx_v_seed;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3975, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3989, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41532,7 +41675,7 @@ static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4027
+/* "pywrapfst.pyx":4041
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -41545,7 +41688,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
   PyObject *__pyx_v_call_arc_labeling = ((PyObject *)__pyx_n_u_input);
   PyObject *__pyx_v_return_arc_labeling = ((PyObject *)__pyx_n_u_neither);
 
-  /* "pywrapfst.pyx":4030
+  /* "pywrapfst.pyx":4044
  *                          call_arc_labeling="input",
  *                          return_arc_labeling="neither",
  *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -41594,7 +41737,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
     }
   }
 
-  /* "pywrapfst.pyx":4071
+  /* "pywrapfst.pyx":4085
  *   cdef Fst _pfst
  *   cdef vector[fst.LabelFstClassPair] _pairs
  *   for (_label, _pfst) in pairs:             # <<<<<<<<<<<<<<
@@ -41605,26 +41748,26 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
     __pyx_t_1 = __pyx_v_pairs; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4071, __pyx_L1_error)
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4085, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4071, __pyx_L1_error)
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4085, __pyx_L1_error)
   }
   for (;;) {
     if (likely(!__pyx_t_3)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
         if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4071, __pyx_L1_error)
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4085, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4071, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4085, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       } else {
         if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4071, __pyx_L1_error)
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4085, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4071, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4085, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
@@ -41634,7 +41777,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 4071, __pyx_L1_error)
+          else __PYX_ERR(0, 4085, __pyx_L1_error)
         }
         break;
       }
@@ -41646,7 +41789,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        __PYX_ERR(0, 4071, __pyx_L1_error)
+        __PYX_ERR(0, 4085, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -41659,15 +41802,15 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4071, __pyx_L1_error)
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4085, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4071, __pyx_L1_error)
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4085, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4071, __pyx_L1_error)
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4085, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
@@ -41675,7 +41818,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_GOTREF(__pyx_t_5);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 4071, __pyx_L1_error)
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 4085, __pyx_L1_error)
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L6_unpacking_done;
@@ -41683,17 +41826,17 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      __PYX_ERR(0, 4071, __pyx_L1_error)
+      __PYX_ERR(0, 4085, __pyx_L1_error)
       __pyx_L6_unpacking_done:;
     }
-    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
+    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4085, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4071, __pyx_L1_error)
+    if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4085, __pyx_L1_error)
     __pyx_v__label = __pyx_t_9;
     __Pyx_XDECREF_SET(__pyx_v__pfst, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_6));
     __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":4072
+    /* "pywrapfst.pyx":4086
  *   cdef vector[fst.LabelFstClassPair] _pairs
  *   for (_label, _pfst) in pairs:
  *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))             # <<<<<<<<<<<<<<
@@ -41702,22 +41845,22 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
  */
     if (unlikely(((PyObject *)__pyx_v__pfst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4072, __pyx_L1_error)
+      __PYX_ERR(0, 4086, __pyx_L1_error)
     }
     try {
       __pyx_t_10 = __pyx_t_10cpywrapfst_LabelFstClassPair(__pyx_v__label, __pyx_v__pfst->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4072, __pyx_L1_error)
+      __PYX_ERR(0, 4086, __pyx_L1_error)
     }
     try {
       __pyx_v__pairs.push_back(__pyx_t_10);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4072, __pyx_L1_error)
+      __PYX_ERR(0, 4086, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":4071
+    /* "pywrapfst.pyx":4085
  *   cdef Fst _pfst
  *   cdef vector[fst.LabelFstClassPair] _pairs
  *   for (_label, _pfst) in pairs:             # <<<<<<<<<<<<<<
@@ -41727,7 +41870,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4074
+  /* "pywrapfst.pyx":4088
  *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))             # <<<<<<<<<<<<<<
@@ -41736,45 +41879,45 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
  */
   __pyx_v__tfst.reset(new fst::script::VectorFstClass((__pyx_v__pairs[0]).second->ArcType()));
 
-  /* "pywrapfst.pyx":4076
+  /* "pywrapfst.pyx":4090
  *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  *   cdef fst.ReplaceLabelType _cal = _get_replace_label_type(
  *       tostring(call_arc_labeling),             # <<<<<<<<<<<<<<
  *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4076, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4090, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4075
+  /* "pywrapfst.pyx":4089
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  *   cdef fst.ReplaceLabelType _cal = _get_replace_label_type(             # <<<<<<<<<<<<<<
  *       tostring(call_arc_labeling),
  *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4075, __pyx_L1_error)
+  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4089, __pyx_L1_error)
   __pyx_v__cal = __pyx_t_12;
 
-  /* "pywrapfst.pyx":4079
+  /* "pywrapfst.pyx":4093
  *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(
  *       tostring(return_arc_labeling),             # <<<<<<<<<<<<<<
  *       epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] _opts
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4079, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4093, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4078
+  /* "pywrapfst.pyx":4092
  *       tostring(call_arc_labeling),
  *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(             # <<<<<<<<<<<<<<
  *       tostring(return_arc_labeling),
  *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4078, __pyx_L1_error)
+  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4092, __pyx_L1_error)
   __pyx_v__ral = __pyx_t_12;
 
-  /* "pywrapfst.pyx":4082
+  /* "pywrapfst.pyx":4096
  *       epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] _opts
  *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))             # <<<<<<<<<<<<<<
@@ -41783,7 +41926,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
  */
   __pyx_v__opts.reset(new fst::script::ReplaceOptions((__pyx_v__pairs[0]).first, __pyx_v__cal, __pyx_v__ral, __pyx_v_return_label));
 
-  /* "pywrapfst.pyx":4083
+  /* "pywrapfst.pyx":4097
  *   cdef unique_ptr[fst.ReplaceOptions] _opts
  *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))
  *   fst.Replace(_pairs, _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -41792,7 +41935,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
  */
   fst::script::Replace(__pyx_v__pairs, __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":4084
+  /* "pywrapfst.pyx":4098
  *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))
  *   fst.Replace(_pairs, _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -41800,13 +41943,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4084, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4098, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4027
+  /* "pywrapfst.pyx":4041
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -41898,7 +42041,7 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 4027, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 4041, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41919,10 +42062,10 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
     __pyx_v_call_arc_labeling = values[1];
     __pyx_v_return_arc_labeling = values[2];
     if (values[3]) {
-      __pyx_v_epsilon_on_replace = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_epsilon_on_replace == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4030, __pyx_L3_error)
+      __pyx_v_epsilon_on_replace = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_epsilon_on_replace == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4044, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4030
+      /* "pywrapfst.pyx":4044
  *                          call_arc_labeling="input",
  *                          return_arc_labeling="neither",
  *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -41932,14 +42075,14 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
       __pyx_v_epsilon_on_replace = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4031, __pyx_L3_error)
+      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4045, __pyx_L3_error)
     } else {
       __pyx_v_return_label = ((int64)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4027, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4041, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -41947,7 +42090,7 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_50replace(__pyx_self, __pyx_v_pairs, __pyx_v_call_arc_labeling, __pyx_v_return_arc_labeling, __pyx_v_epsilon_on_replace, __pyx_v_return_label);
 
-  /* "pywrapfst.pyx":4027
+  /* "pywrapfst.pyx":4041
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -41975,7 +42118,7 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.return_arc_labeling = __pyx_v_return_arc_labeling;
   __pyx_t_2.epsilon_on_replace = __pyx_v_epsilon_on_replace;
   __pyx_t_2.return_label = __pyx_v_return_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_replace(__pyx_v_pairs, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4027, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_replace(__pyx_v_pairs, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4041, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41992,7 +42135,7 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4087
+/* "pywrapfst.pyx":4101
  * 
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -42017,7 +42160,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct
     }
   }
 
-  /* "pywrapfst.pyx":4107
+  /* "pywrapfst.pyx":4121
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -42026,11 +42169,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4107, __pyx_L1_error)
+    __PYX_ERR(0, 4121, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4108
+  /* "pywrapfst.pyx":4122
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)             # <<<<<<<<<<<<<<
@@ -42039,11 +42182,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4108, __pyx_L1_error)
+    __PYX_ERR(0, 4122, __pyx_L1_error)
   }
   fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":4109
+  /* "pywrapfst.pyx":4123
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -42051,13 +42194,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4109, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4123, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4087
+  /* "pywrapfst.pyx":4101
  * 
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -42115,7 +42258,7 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4087, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4101, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42128,20 +42271,20 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_require_superinitial = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_require_superinitial == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4087, __pyx_L3_error)
+      __pyx_v_require_superinitial = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_require_superinitial == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4101, __pyx_L3_error)
     } else {
       __pyx_v_require_superinitial = ((bool)1);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4087, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4101, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.reverse", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4087, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4101, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_52reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
@@ -42165,7 +42308,7 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.require_superinitial = __pyx_v_require_superinitial;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_reverse(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4087, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_reverse(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4101, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42182,7 +42325,7 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4115
+/* "pywrapfst.pyx":4129
  * 
  * 
  * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42195,7 +42338,7 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
   int64 __pyx_v_nstate = __pyx_k__48;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":4120
+  /* "pywrapfst.pyx":4134
  *                             int64 nstate=fst.kNoStateId,
  *                             queue_type="auto",
  *                             bool reverse=False) except *:             # <<<<<<<<<<<<<<
@@ -42227,7 +42370,7 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
     }
   }
 
-  /* "pywrapfst.pyx":4122
+  /* "pywrapfst.pyx":4136
  *                             bool reverse=False) except *:
  *   cdef unique_ptr[fst.ShortestDistanceOptions] _opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -42237,7 +42380,7 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_1 = (__pyx_v_reverse != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":4125
+    /* "pywrapfst.pyx":4139
  *     # Only the simpler signature supports shortest distance to final states;
  *     # `nstate` and `queue_type` arguments are ignored.
  *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)             # <<<<<<<<<<<<<<
@@ -42246,11 +42389,11 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4125, __pyx_L1_error)
+      __PYX_ERR(0, 4139, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance, 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":4122
+    /* "pywrapfst.pyx":4136
  *                             bool reverse=False) except *:
  *   cdef unique_ptr[fst.ShortestDistanceOptions] _opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -42260,35 +42403,35 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":4127
+  /* "pywrapfst.pyx":4141
  *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)
  *   else:
  *     _opts.reset(             # <<<<<<<<<<<<<<
  *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
- *                                         fst.ANY_ARC_FILTER,
+ *                                         fst.ArcFilterType.ANY_ARC_FILTER,
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":4128
+    /* "pywrapfst.pyx":4142
  *   else:
  *     _opts.reset(
  *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *                                         fst.ANY_ARC_FILTER,
+ *                                         fst.ArcFilterType.ANY_ARC_FILTER,
  *                                         nstate,
  */
-    __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4128, __pyx_L1_error)
-    __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4128, __pyx_L1_error)
+    __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4142, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4142, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4127
+    /* "pywrapfst.pyx":4141
  *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)
  *   else:
  *     _opts.reset(             # <<<<<<<<<<<<<<
  *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
- *                                         fst.ANY_ARC_FILTER,
+ *                                         fst.ArcFilterType.ANY_ARC_FILTER,
  */
-    __pyx_v__opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_3, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
+    __pyx_v__opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_3, fst::script::ArcFilterType::ANY, __pyx_v_nstate, __pyx_v_delta));
 
-    /* "pywrapfst.pyx":4132
+    /* "pywrapfst.pyx":4146
  *                                         nstate,
  *                                         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance, deref(_opts))             # <<<<<<<<<<<<<<
@@ -42297,13 +42440,13 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4132, __pyx_L1_error)
+      __PYX_ERR(0, 4146, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance, (*__pyx_v__opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":4115
+  /* "pywrapfst.pyx":4129
  * 
  * 
  * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42319,7 +42462,7 @@ static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4135
+/* "pywrapfst.pyx":4149
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42395,7 +42538,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4135, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4149, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42414,21 +42557,21 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4136, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4150, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__49;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4137, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4151, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__50;
     }
     __pyx_v_queue_type = values[3];
     if (values[4]) {
-      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4139, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4153, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4139
+      /* "pywrapfst.pyx":4153
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type="auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
@@ -42440,16 +42583,16 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4135, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4149, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.shortestdistance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4135, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4149, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_54shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
 
-  /* "pywrapfst.pyx":4135
+  /* "pywrapfst.pyx":4149
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42483,7 +42626,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":4167
+  /* "pywrapfst.pyx":4181
  *   """
  *   cdef vector[fst.WeightClass] _distance
  *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)             # <<<<<<<<<<<<<<
@@ -42495,9 +42638,9 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
   __pyx_t_1.reverse = __pyx_v_reverse;
-  __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, (&__pyx_v__distance), &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4167, __pyx_L1_error)
+  __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, (&__pyx_v__distance), &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4181, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4168
+  /* "pywrapfst.pyx":4182
  *   cdef vector[fst.WeightClass] _distance
  *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
  *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())             # <<<<<<<<<<<<<<
@@ -42506,10 +42649,10 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
  */
   __Pyx_XDECREF(__pyx_r);
   { /* enter inner scope */
-    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4168, __pyx_L1_error)
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4182, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
 
-    /* "pywrapfst.pyx":4169
+    /* "pywrapfst.pyx":4183
  *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
  *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())
  *           for weight in _distance]             # <<<<<<<<<<<<<<
@@ -42523,7 +42666,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
       ++__pyx_t_3;
       __pyx_7genexpr__pyx_v_weight = __pyx_t_4;
 
-      /* "pywrapfst.pyx":4168
+      /* "pywrapfst.pyx":4182
  *   cdef vector[fst.WeightClass] _distance
  *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
  *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())             # <<<<<<<<<<<<<<
@@ -42532,13 +42675,13 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
  */
       if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-        __PYX_ERR(0, 4168, __pyx_L1_error)
+        __PYX_ERR(0, 4182, __pyx_L1_error)
       }
-      __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_ifst->_fst.get()->WeightType()); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4168, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_ifst->_fst.get()->WeightType()); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4182, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4168, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4182, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4168, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4182, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_5);
       PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
@@ -42546,13 +42689,13 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
       PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
       __pyx_t_5 = 0;
       __pyx_t_6 = 0;
-      __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4168, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4182, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 4168, __pyx_L1_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 4182, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-      /* "pywrapfst.pyx":4169
+      /* "pywrapfst.pyx":4183
  *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
  *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())
  *           for weight in _distance]             # <<<<<<<<<<<<<<
@@ -42565,7 +42708,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4135
+  /* "pywrapfst.pyx":4149
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42587,7 +42730,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4172
+/* "pywrapfst.pyx":4186
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42602,7 +42745,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
   int64 __pyx_v_nstate = __pyx_k__52;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":4177
+  /* "pywrapfst.pyx":4191
  *                               int64 nstate=fst.kNoStateId,
  *                               queue_type="auto",
  *                               bool unique=False,             # <<<<<<<<<<<<<<
@@ -42611,7 +42754,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4178
+  /* "pywrapfst.pyx":4192
  *                               queue_type="auto",
  *                               bool unique=False,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -42653,7 +42796,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
     }
   }
 
-  /* "pywrapfst.pyx":4210
+  /* "pywrapfst.pyx":4224
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -42662,11 +42805,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4210, __pyx_L1_error)
+    __PYX_ERR(0, 4224, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4212
+  /* "pywrapfst.pyx":4226
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -42675,30 +42818,30 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4212, __pyx_L1_error)
+    __PYX_ERR(0, 4226, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4213
+  /* "pywrapfst.pyx":4227
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass _weight = _get_WeightClass_or_zero(ifst.weight_type(),
  *                                                           weight)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ShortestPathOptions] _opts
  *   _opts.reset(
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4212, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4226, __pyx_L1_error)
   __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4216
+  /* "pywrapfst.pyx":4230
  *   cdef unique_ptr[fst.ShortestPathOptions] _opts
  *   _opts.reset(
  *       new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
  *                                   nshortest,
  *                                   unique,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4216, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4216, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4230, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4230, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4215
+  /* "pywrapfst.pyx":4229
  *                                                           weight)
  *   cdef unique_ptr[fst.ShortestPathOptions] _opts
  *   _opts.reset(             # <<<<<<<<<<<<<<
@@ -42707,7 +42850,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  */
   __pyx_v__opts.reset(new fst::script::ShortestPathOptions(__pyx_t_3, __pyx_v_nshortest, __pyx_v_unique, __pyx_v_delta, __pyx_v__weight, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":4222
+  /* "pywrapfst.pyx":4236
  *                                   _weight,
  *                                   nstate))
  *   fst.ShortestPath(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
@@ -42716,11 +42859,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4222, __pyx_L1_error)
+    __PYX_ERR(0, 4236, __pyx_L1_error)
   }
   fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":4223
+  /* "pywrapfst.pyx":4237
  *                                   nstate))
  *   fst.ShortestPath(deref(ifst._fst), _tfst.get(), deref(_opts))
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -42728,13 +42871,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4223, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4237, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4172
+  /* "pywrapfst.pyx":4186
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42775,7 +42918,7 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_u_auto);
 
-    /* "pywrapfst.pyx":4178
+    /* "pywrapfst.pyx":4192
  *                               queue_type="auto",
  *                               bool unique=False,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -42847,7 +42990,7 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4172, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4186, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42870,26 +43013,26 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4173, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4187, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__51;
     }
     if (values[2]) {
-      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4174, __pyx_L3_error)
+      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4188, __pyx_L3_error)
     } else {
       __pyx_v_nshortest = ((int32)1);
     }
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4175, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4189, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__52;
     }
     __pyx_v_queue_type = values[4];
     if (values[5]) {
-      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4177, __pyx_L3_error)
+      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4191, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4177
+      /* "pywrapfst.pyx":4191
  *                               int64 nstate=fst.kNoStateId,
  *                               queue_type="auto",
  *                               bool unique=False,             # <<<<<<<<<<<<<<
@@ -42902,16 +43045,16 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4172, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4186, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.shortestpath", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4172, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4186, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_56shortestpath(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nshortest, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_unique, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":4172
+  /* "pywrapfst.pyx":4186
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42945,7 +43088,7 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.unique = __pyx_v_unique;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_shortestpath(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4172, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_shortestpath(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4186, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42962,7 +43105,7 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4226
+/* "pywrapfst.pyx":4240
  * 
  * 
  * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -42981,7 +43124,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("statemap", 0);
 
-  /* "pywrapfst.pyx":4249
+  /* "pywrapfst.pyx":4263
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, 1., None)             # <<<<<<<<<<<<<<
@@ -42994,13 +43137,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = 1.;
   __pyx_t_2.weight = Py_None;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4249, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4263, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4226
+  /* "pywrapfst.pyx":4240
  * 
  * 
  * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -43054,11 +43197,11 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_map_type)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4226, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4240, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4226, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4240, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -43071,13 +43214,13 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4226, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4240, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.statemap", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4226, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4240, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_58statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
@@ -43098,7 +43241,7 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("statemap", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_statemap(__pyx_v_ifst, __pyx_v_map_type, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4226, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_statemap(__pyx_v_ifst, __pyx_v_map_type, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4240, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43115,7 +43258,7 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4252
+/* "pywrapfst.pyx":4266
  * 
  * 
  * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
@@ -43134,7 +43277,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4272
+  /* "pywrapfst.pyx":4286
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -43143,11 +43286,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4272, __pyx_L1_error)
+    __PYX_ERR(0, 4286, __pyx_L1_error)
   }
   __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4273
+  /* "pywrapfst.pyx":4287
  *   cdef unique_ptr[fst.VectorFstClass] _tfst
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), _tfst.get())             # <<<<<<<<<<<<<<
@@ -43156,11 +43299,11 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4273, __pyx_L1_error)
+    __PYX_ERR(0, 4287, __pyx_L1_error)
   }
   fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get());
 
-  /* "pywrapfst.pyx":4274
+  /* "pywrapfst.pyx":4288
  *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), _tfst.get())
  *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -43168,13 +43311,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(st
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4274, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4288, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4252
+  /* "pywrapfst.pyx":4266
  * 
  * 
  * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
@@ -43203,7 +43346,7 @@ static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObjec
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("synchronize (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4252, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4266, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_60synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_ifst));
 
   /* function exit code */
@@ -43224,7 +43367,7 @@ static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("synchronize", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4252, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4266, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43241,7 +43384,7 @@ static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4331
+/* "pywrapfst.pyx":4345
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -43274,7 +43417,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
     values[0] = ((PyObject*)__pyx_n_u_vector);
     values[1] = ((PyObject*)__pyx_n_u_standard);
 
-    /* "pywrapfst.pyx":4334
+    /* "pywrapfst.pyx":4348
  *                 str fst_type="vector",
  *                 str arc_type="standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -43283,7 +43426,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":4335
+    /* "pywrapfst.pyx":4349
  *                 str arc_type="standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -43292,7 +43435,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
  */
     values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":4336
+    /* "pywrapfst.pyx":4350
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -43390,7 +43533,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4331, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4345, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -43424,10 +43567,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[3]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[4]);
     if (values[5]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4337, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4351, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4337
+      /* "pywrapfst.pyx":4351
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -43437,10 +43580,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_acceptor = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_keep_isymbols = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_keep_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4338, __pyx_L3_error)
+      __pyx_v_keep_isymbols = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_keep_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4352, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4338
+      /* "pywrapfst.pyx":4352
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -43450,10 +43593,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_isymbols = ((bool)0);
     }
     if (values[7]) {
-      __pyx_v_keep_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_keep_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4339, __pyx_L3_error)
+      __pyx_v_keep_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_keep_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4353, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4339
+      /* "pywrapfst.pyx":4353
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -43463,10 +43606,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_osymbols = ((bool)0);
     }
     if (values[8]) {
-      __pyx_v_keep_state_numbering = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_keep_state_numbering == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4340, __pyx_L3_error)
+      __pyx_v_keep_state_numbering = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_keep_state_numbering == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4354, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4340
+      /* "pywrapfst.pyx":4354
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -43476,10 +43619,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_state_numbering = ((bool)0);
     }
     if (values[9]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4341, __pyx_L3_error)
+      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4355, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4341
+      /* "pywrapfst.pyx":4355
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -43491,20 +43634,20 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4331, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4345, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Compiler.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst_type), (&PyUnicode_Type), 1, "fst_type", 1))) __PYX_ERR(0, 4332, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc_type), (&PyUnicode_Type), 1, "arc_type", 1))) __PYX_ERR(0, 4333, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4334, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4335, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4336, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst_type), (&PyUnicode_Type), 1, "fst_type", 1))) __PYX_ERR(0, 4346, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc_type), (&PyUnicode_Type), 1, "arc_type", 1))) __PYX_ERR(0, 4347, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4348, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4349, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4350, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_8Compiler___cinit__(((struct __pyx_obj_9pywrapfst_Compiler *)__pyx_v_self), __pyx_v_fst_type, __pyx_v_arc_type, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_keep_isymbols, __pyx_v_keep_osymbols, __pyx_v_keep_state_numbering, __pyx_v_allow_negative_labels);
 
-  /* "pywrapfst.pyx":4331
+  /* "pywrapfst.pyx":4345
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -43533,7 +43676,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4342
+  /* "pywrapfst.pyx":4356
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -43542,39 +43685,39 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4342, __pyx_L1_error)
+    __PYX_ERR(0, 4356, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4343
+  /* "pywrapfst.pyx":4357
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)             # <<<<<<<<<<<<<<
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4343, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4357, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4343, __pyx_L1_error)
+    __PYX_ERR(0, 4357, __pyx_L1_error)
   }
   __pyx_v_self->_fst_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4344
+  /* "pywrapfst.pyx":4358
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)             # <<<<<<<<<<<<<<
  *     self._isymbols = NULL
  *     if isymbols is not None:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4344, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4358, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4344, __pyx_L1_error)
+    __PYX_ERR(0, 4358, __pyx_L1_error)
   }
   __pyx_v_self->_arc_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4345
+  /* "pywrapfst.pyx":4359
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
@@ -43583,11 +43726,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4345, __pyx_L1_error)
+    __PYX_ERR(0, 4359, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4346
+  /* "pywrapfst.pyx":4360
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -43598,7 +43741,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_3 = (__pyx_t_2 != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4347
+    /* "pywrapfst.pyx":4361
  *     self._isymbols = NULL
  *     if isymbols is not None:
  *       self._isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43607,16 +43750,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4347, __pyx_L1_error)
+      __PYX_ERR(0, 4361, __pyx_L1_error)
     }
-    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_isymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_isymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4347, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_isymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_isymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4361, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-      __PYX_ERR(0, 4347, __pyx_L1_error)
+      __PYX_ERR(0, 4361, __pyx_L1_error)
     }
     __pyx_v_self->_isymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4346
+    /* "pywrapfst.pyx":4360
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -43625,7 +43768,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4348
+  /* "pywrapfst.pyx":4362
  *     if isymbols is not None:
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
@@ -43634,11 +43777,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4348, __pyx_L1_error)
+    __PYX_ERR(0, 4362, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4349
+  /* "pywrapfst.pyx":4363
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -43649,7 +43792,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_2 = (__pyx_t_3 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":4350
+    /* "pywrapfst.pyx":4364
  *     self._osymbols = NULL
  *     if osymbols is not None:
  *       self._osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43658,16 +43801,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4350, __pyx_L1_error)
+      __PYX_ERR(0, 4364, __pyx_L1_error)
     }
-    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_osymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_osymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4350, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_osymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_osymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4364, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-      __PYX_ERR(0, 4350, __pyx_L1_error)
+      __PYX_ERR(0, 4364, __pyx_L1_error)
     }
     __pyx_v_self->_osymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4349
+    /* "pywrapfst.pyx":4363
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -43676,7 +43819,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4351
+  /* "pywrapfst.pyx":4365
  *     if osymbols is not None:
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -43685,11 +43828,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4351, __pyx_L1_error)
+    __PYX_ERR(0, 4365, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4352
+  /* "pywrapfst.pyx":4366
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -43700,7 +43843,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_3 = (__pyx_t_2 != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4353
+    /* "pywrapfst.pyx":4367
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43709,16 +43852,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4353, __pyx_L1_error)
+      __PYX_ERR(0, 4367, __pyx_L1_error)
     }
-    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_ssymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4353, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_ssymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4367, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-      __PYX_ERR(0, 4353, __pyx_L1_error)
+      __PYX_ERR(0, 4367, __pyx_L1_error)
     }
     __pyx_v_self->_ssymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4352
+    /* "pywrapfst.pyx":4366
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -43727,7 +43870,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4354
+  /* "pywrapfst.pyx":4368
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
@@ -43736,11 +43879,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4354, __pyx_L1_error)
+    __PYX_ERR(0, 4368, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4355
+  /* "pywrapfst.pyx":4369
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
@@ -43749,11 +43892,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4355, __pyx_L1_error)
+    __PYX_ERR(0, 4369, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4356
+  /* "pywrapfst.pyx":4370
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -43762,11 +43905,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4356, __pyx_L1_error)
+    __PYX_ERR(0, 4370, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4357
+  /* "pywrapfst.pyx":4371
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -43775,11 +43918,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4357, __pyx_L1_error)
+    __PYX_ERR(0, 4371, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4358
+  /* "pywrapfst.pyx":4372
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
@@ -43788,11 +43931,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4358, __pyx_L1_error)
+    __PYX_ERR(0, 4372, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4331
+  /* "pywrapfst.pyx":4345
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -43811,7 +43954,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4360
+/* "pywrapfst.pyx":4374
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
@@ -43842,7 +43985,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4360, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4374, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_3compile)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -43859,10 +44002,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4360, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4374, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4360, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4374, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -43881,162 +44024,162 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     #endif
   }
 
-  /* "pywrapfst.pyx":4375
+  /* "pywrapfst.pyx":4389
  *     """
  *     cdef unique_ptr[fst.FstClass] _tfst
- *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *                                        b"<pywrapfst>",
- *                                        self._fst_type,
+ *     _tfst = fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
+ *                                    b"<pywrapfst>",
+ *                                    self._fst_type,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4375, __pyx_L1_error)
+    __PYX_ERR(0, 4389, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4377
- *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
- *                                        b"<pywrapfst>",
- *                                        self._fst_type,             # <<<<<<<<<<<<<<
- *                                        self._arc_type,
- *                                        self._isymbols,
+  /* "pywrapfst.pyx":4391
+ *     _tfst = fst.CompileFstInternal(deref(self._sstrm),
+ *                                    b"<pywrapfst>",
+ *                                    self._fst_type,             # <<<<<<<<<<<<<<
+ *                                    self._arc_type,
+ *                                    self._isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4377, __pyx_L1_error)
+    __PYX_ERR(0, 4391, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4378
- *                                        b"<pywrapfst>",
- *                                        self._fst_type,
- *                                        self._arc_type,             # <<<<<<<<<<<<<<
- *                                        self._isymbols,
- *                                        self._osymbols,
+  /* "pywrapfst.pyx":4392
+ *                                    b"<pywrapfst>",
+ *                                    self._fst_type,
+ *                                    self._arc_type,             # <<<<<<<<<<<<<<
+ *                                    self._isymbols,
+ *                                    self._osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4378, __pyx_L1_error)
+    __PYX_ERR(0, 4392, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4379
- *                                        self._fst_type,
- *                                        self._arc_type,
- *                                        self._isymbols,             # <<<<<<<<<<<<<<
- *                                        self._osymbols,
- *                                        self._ssymbols,
+  /* "pywrapfst.pyx":4393
+ *                                    self._fst_type,
+ *                                    self._arc_type,
+ *                                    self._isymbols,             # <<<<<<<<<<<<<<
+ *                                    self._osymbols,
+ *                                    self._ssymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4379, __pyx_L1_error)
+    __PYX_ERR(0, 4393, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4380
- *                                        self._arc_type,
- *                                        self._isymbols,
- *                                        self._osymbols,             # <<<<<<<<<<<<<<
- *                                        self._ssymbols,
- *                                        self._acceptor,
+  /* "pywrapfst.pyx":4394
+ *                                    self._arc_type,
+ *                                    self._isymbols,
+ *                                    self._osymbols,             # <<<<<<<<<<<<<<
+ *                                    self._ssymbols,
+ *                                    self._acceptor,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4380, __pyx_L1_error)
+    __PYX_ERR(0, 4394, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4381
- *                                        self._isymbols,
- *                                        self._osymbols,
- *                                        self._ssymbols,             # <<<<<<<<<<<<<<
- *                                        self._acceptor,
- *                                        self._keep_isymbols,
+  /* "pywrapfst.pyx":4395
+ *                                    self._isymbols,
+ *                                    self._osymbols,
+ *                                    self._ssymbols,             # <<<<<<<<<<<<<<
+ *                                    self._acceptor,
+ *                                    self._keep_isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4381, __pyx_L1_error)
+    __PYX_ERR(0, 4395, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4382
- *                                        self._osymbols,
- *                                        self._ssymbols,
- *                                        self._acceptor,             # <<<<<<<<<<<<<<
- *                                        self._keep_isymbols,
- *                                        self._keep_osymbols,
+  /* "pywrapfst.pyx":4396
+ *                                    self._osymbols,
+ *                                    self._ssymbols,
+ *                                    self._acceptor,             # <<<<<<<<<<<<<<
+ *                                    self._keep_isymbols,
+ *                                    self._keep_osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4382, __pyx_L1_error)
+    __PYX_ERR(0, 4396, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4383
- *                                        self._ssymbols,
- *                                        self._acceptor,
- *                                        self._keep_isymbols,             # <<<<<<<<<<<<<<
- *                                        self._keep_osymbols,
- *                                        self._keep_state_numbering,
+  /* "pywrapfst.pyx":4397
+ *                                    self._ssymbols,
+ *                                    self._acceptor,
+ *                                    self._keep_isymbols,             # <<<<<<<<<<<<<<
+ *                                    self._keep_osymbols,
+ *                                    self._keep_state_numbering,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4383, __pyx_L1_error)
+    __PYX_ERR(0, 4397, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4384
- *                                        self._acceptor,
- *                                        self._keep_isymbols,
- *                                        self._keep_osymbols,             # <<<<<<<<<<<<<<
- *                                        self._keep_state_numbering,
- *                                        self._allow_negative_labels))
+  /* "pywrapfst.pyx":4398
+ *                                    self._acceptor,
+ *                                    self._keep_isymbols,
+ *                                    self._keep_osymbols,             # <<<<<<<<<<<<<<
+ *                                    self._keep_state_numbering,
+ *                                    self._allow_negative_labels)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4384, __pyx_L1_error)
+    __PYX_ERR(0, 4398, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4385
- *                                        self._keep_isymbols,
- *                                        self._keep_osymbols,
- *                                        self._keep_state_numbering,             # <<<<<<<<<<<<<<
- *                                        self._allow_negative_labels))
+  /* "pywrapfst.pyx":4399
+ *                                    self._keep_isymbols,
+ *                                    self._keep_osymbols,
+ *                                    self._keep_state_numbering,             # <<<<<<<<<<<<<<
+ *                                    self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4385, __pyx_L1_error)
+    __PYX_ERR(0, 4399, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4386
- *                                        self._keep_osymbols,
- *                                        self._keep_state_numbering,
- *                                        self._allow_negative_labels))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4400
+ *                                    self._keep_osymbols,
+ *                                    self._keep_state_numbering,
+ *                                    self._allow_negative_labels)             # <<<<<<<<<<<<<<
  *     self._sstrm.reset(new stringstream())
  *     if _tfst.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4386, __pyx_L1_error)
+    __PYX_ERR(0, 4400, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4375
+  /* "pywrapfst.pyx":4389
  *     """
  *     cdef unique_ptr[fst.FstClass] _tfst
- *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *                                        b"<pywrapfst>",
- *                                        self._fst_type,
+ *     _tfst = fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
+ *                                    b"<pywrapfst>",
+ *                                    self._fst_type,
  */
-  __pyx_v__tfst.reset(fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_k_pywrapfst, __pyx_v_self->_fst_type, __pyx_v_self->_arc_type, __pyx_v_self->_isymbols, __pyx_v_self->_osymbols, __pyx_v_self->_ssymbols, __pyx_v_self->_acceptor, __pyx_v_self->_keep_isymbols, __pyx_v_self->_keep_osymbols, __pyx_v_self->_keep_state_numbering, __pyx_v_self->_allow_negative_labels));
+  __pyx_v__tfst = fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_k_pywrapfst, __pyx_v_self->_fst_type, __pyx_v_self->_arc_type, __pyx_v_self->_isymbols, __pyx_v_self->_osymbols, __pyx_v_self->_ssymbols, __pyx_v_self->_acceptor, __pyx_v_self->_keep_isymbols, __pyx_v_self->_keep_osymbols, __pyx_v_self->_keep_state_numbering, __pyx_v_self->_allow_negative_labels);
 
-  /* "pywrapfst.pyx":4387
- *                                        self._keep_state_numbering,
- *                                        self._allow_negative_labels))
+  /* "pywrapfst.pyx":4401
+ *                                    self._keep_state_numbering,
+ *                                    self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
  *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4387, __pyx_L1_error)
+    __PYX_ERR(0, 4401, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4388
- *                                        self._allow_negative_labels))
+  /* "pywrapfst.pyx":4402
+ *                                    self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())
  *     if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
@@ -44045,14 +44188,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
   __pyx_t_5 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4389
+    /* "pywrapfst.pyx":4403
  *     self._sstrm.reset(new stringstream())
  *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
  *     return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4389, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4403, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -44066,15 +44209,15 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Compilation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Compilation_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4389, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4403, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4389, __pyx_L1_error)
+    __PYX_ERR(0, 4403, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4388
- *                                        self._allow_negative_labels))
+    /* "pywrapfst.pyx":4402
+ *                                    self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())
  *     if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
@@ -44082,7 +44225,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
  */
   }
 
-  /* "pywrapfst.pyx":4390
+  /* "pywrapfst.pyx":4404
  *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  *     return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
@@ -44090,13 +44233,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
  *   cpdef void write(self, expression):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4390, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4404, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4360
+  /* "pywrapfst.pyx":4374
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
@@ -44141,7 +44284,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compile", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4360, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4374, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44158,7 +44301,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4392
+/* "pywrapfst.pyx":4406
  *     return _init_XFst(_tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -44190,7 +44333,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4392, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4406, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_5write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44206,7 +44349,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_expression) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_expression);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4392, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4406, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -44226,17 +44369,17 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     #endif
   }
 
-  /* "pywrapfst.pyx":4408
+  /* "pywrapfst.pyx":4422
  *       expression: A string expression to add to compiler string buffer.
  *     """
  *     cdef string _line = tostring(expression)             # <<<<<<<<<<<<<<
  *     if not _line.empty() and _line.back() != b'\n':
  *       _line.append(b'\n')
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4408, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4422, __pyx_L1_error)
   __pyx_v__line = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4409
+  /* "pywrapfst.pyx":4423
  *     """
  *     cdef string _line = tostring(expression)
  *     if not _line.empty() and _line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -44254,7 +44397,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4410
+    /* "pywrapfst.pyx":4424
  *     cdef string _line = tostring(expression)
  *     if not _line.empty() and _line.back() != b'\n':
  *       _line.append(b'\n')             # <<<<<<<<<<<<<<
@@ -44263,7 +44406,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
     (void)(__pyx_v__line.append(((char const *)"\n")));
 
-    /* "pywrapfst.pyx":4409
+    /* "pywrapfst.pyx":4423
  *     """
  *     cdef string _line = tostring(expression)
  *     if not _line.empty() and _line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -44272,7 +44415,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   }
 
-  /* "pywrapfst.pyx":4411
+  /* "pywrapfst.pyx":4425
  *     if not _line.empty() and _line.back() != b'\n':
  *       _line.append(b'\n')
  *     deref(self._sstrm) << _line             # <<<<<<<<<<<<<<
@@ -44281,11 +44424,11 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4411, __pyx_L1_error)
+    __PYX_ERR(0, 4425, __pyx_L1_error)
   }
   (void)(((*__pyx_v_self->_sstrm) << __pyx_v__line));
 
-  /* "pywrapfst.pyx":4392
+  /* "pywrapfst.pyx":4406
  *     return _init_XFst(_tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -44328,7 +44471,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_8Compiler_write(__pyx_v_self, __pyx_v_expression, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4392, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_8Compiler_write(__pyx_v_self, __pyx_v_expression, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4406, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44458,7 +44601,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4433
+/* "pywrapfst.pyx":4447
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44492,32 +44635,32 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4434
+  /* "pywrapfst.pyx":4448
  * 
  *   def __init__(self):
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 4434, __pyx_L1_error)
+  __PYX_ERR(0, 4448, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4433
+  /* "pywrapfst.pyx":4447
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44535,7 +44678,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4436
+/* "pywrapfst.pyx":4450
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44569,7 +44712,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4437
+  /* "pywrapfst.pyx":4451
  * 
  *   def __repr__(self):
  *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -44577,7 +44720,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -44587,9 +44730,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4437, __pyx_L1_error)
+    __PYX_ERR(0, 4451, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
   __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -44600,9 +44743,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_2 += 16;
   __Pyx_GIVEREF(__pyx_kp_u_FarReader_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_FarReader_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -44614,14 +44757,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4437, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4436
+  /* "pywrapfst.pyx":4450
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44642,7 +44785,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4440
+/* "pywrapfst.pyx":4454
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44689,31 +44832,31 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("open", 0);
 
-  /* "pywrapfst.pyx":4458
+  /* "pywrapfst.pyx":4472
  *       FstIOError: Read failed.
  *     """
  *     cdef vector[string] _sources = [path_tostring(source) for source in sources]             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.FarReaderClass] _tfar
- *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     _tfar = fst.FarReaderClass.Open(_sources)
  */
   { /* enter inner scope */
-    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4458, __pyx_L5_error)
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4472, __pyx_L5_error)
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_t_2 = __pyx_v_sources; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
     for (;;) {
       if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 4458, __pyx_L5_error)
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 4472, __pyx_L5_error)
       #else
-      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4458, __pyx_L5_error)
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4472, __pyx_L5_error)
       __Pyx_GOTREF(__pyx_t_4);
       #endif
       __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_source, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_8genexpr1__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4458, __pyx_L5_error)
-      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4458, __pyx_L5_error)
+      __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_8genexpr1__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4472, __pyx_L5_error)
+      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4472, __pyx_L5_error)
       __Pyx_GOTREF(__pyx_t_4);
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 4458, __pyx_L5_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 4472, __pyx_L5_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     }
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -44724,22 +44867,22 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     goto __pyx_L1_error;
     __pyx_L8_exit_scope:;
   } /* exit inner scope */
-  __pyx_t_6 = __pyx_convert_vector_from_py_std_3a__3a_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4458, __pyx_L1_error)
+  __pyx_t_6 = __pyx_convert_vector_from_py_std_3a__3a_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4472, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v__sources = __pyx_t_6;
 
-  /* "pywrapfst.pyx":4460
+  /* "pywrapfst.pyx":4474
  *     cdef vector[string] _sources = [path_tostring(source) for source in sources]
  *     cdef unique_ptr[fst.FarReaderClass] _tfar
- *     _tfar.reset(fst.FarReaderClass.Open(_sources))             # <<<<<<<<<<<<<<
+ *     _tfar = fst.FarReaderClass.Open(_sources)             # <<<<<<<<<<<<<<
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Read failed: {sources!r}")
  */
-  __pyx_v__tfar.reset(fst::script::FarReaderClass::Open(__pyx_v__sources));
+  __pyx_v__tfar = fst::script::FarReaderClass::Open(__pyx_v__sources);
 
-  /* "pywrapfst.pyx":4461
+  /* "pywrapfst.pyx":4475
  *     cdef unique_ptr[fst.FarReaderClass] _tfar
- *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     _tfar = fst.FarReaderClass.Open(_sources)
  *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstIOError(f"Read failed: {sources!r}")
  *     cdef FarReader reader = FarReader.__new__(FarReader)
@@ -44747,18 +44890,18 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_t_7 = ((__pyx_v__tfar.get() == NULL) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":4462
- *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+    /* "pywrapfst.pyx":4476
+ *     _tfar = fst.FarReaderClass.Open(_sources)
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Read failed: {sources!r}")             # <<<<<<<<<<<<<<
  *     cdef FarReader reader = FarReader.__new__(FarReader)
- *     reader._reader.reset(_tfar.release())
+ *     reader._reader = move(_tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4462, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4476, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sources), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4462, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sources), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4476, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4462, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4476, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -44774,50 +44917,50 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_8) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_8);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4462, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4476, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4462, __pyx_L1_error)
+    __PYX_ERR(0, 4476, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4461
+    /* "pywrapfst.pyx":4475
  *     cdef unique_ptr[fst.FarReaderClass] _tfar
- *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     _tfar = fst.FarReaderClass.Open(_sources)
  *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstIOError(f"Read failed: {sources!r}")
  *     cdef FarReader reader = FarReader.__new__(FarReader)
  */
   }
 
-  /* "pywrapfst.pyx":4463
+  /* "pywrapfst.pyx":4477
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Read failed: {sources!r}")
  *     cdef FarReader reader = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
- *     reader._reader.reset(_tfar.release())
+ *     reader._reader = move(_tfar)
  *     return reader
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4463, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4477, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_reader = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4464
+  /* "pywrapfst.pyx":4478
  *       raise FstIOError(f"Read failed: {sources!r}")
  *     cdef FarReader reader = FarReader.__new__(FarReader)
- *     reader._reader.reset(_tfar.release())             # <<<<<<<<<<<<<<
+ *     reader._reader = move(_tfar)             # <<<<<<<<<<<<<<
  *     return reader
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_reader) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4464, __pyx_L1_error)
+    __PYX_ERR(0, 4478, __pyx_L1_error)
   }
-  __pyx_v_reader->_reader.reset(__pyx_v__tfar.release());
+  __pyx_v_reader->_reader = fst::move<std::unique_ptr<fst::script::FarReaderClass> >(__pyx_v__tfar);
 
-  /* "pywrapfst.pyx":4465
+  /* "pywrapfst.pyx":4479
  *     cdef FarReader reader = FarReader.__new__(FarReader)
- *     reader._reader.reset(_tfar.release())
+ *     reader._reader = move(_tfar)
  *     return reader             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
@@ -44827,7 +44970,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_r = ((PyObject *)__pyx_v_reader);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4440
+  /* "pywrapfst.pyx":4454
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44851,7 +44994,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4467
+/* "pywrapfst.pyx":4481
  *     return reader
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -44881,7 +45024,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4467, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4481, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_7arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44897,10 +45040,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4467, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4481, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4467, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4481, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44919,7 +45062,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4473
+  /* "pywrapfst.pyx":4487
  *     Returns a string indicating the arc type.
  *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
@@ -44928,12 +45071,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4473, __pyx_L1_error)
+    __PYX_ERR(0, 4487, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4467
+  /* "pywrapfst.pyx":4481
  *     return reader
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -44977,7 +45120,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4467, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4481, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44994,7 +45137,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4475
+/* "pywrapfst.pyx":4489
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -45024,7 +45167,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4475, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4489, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45040,10 +45183,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4475, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4489, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4475, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4489, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45062,7 +45205,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4484
+  /* "pywrapfst.pyx":4498
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -45071,12 +45214,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4484, __pyx_L1_error)
+    __PYX_ERR(0, 4498, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4475
+  /* "pywrapfst.pyx":4489
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -45120,7 +45263,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4475, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4489, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45137,7 +45280,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4486
+/* "pywrapfst.pyx":4500
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45167,7 +45310,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4486, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4500, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45183,10 +45326,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4486, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4500, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4486, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4500, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45205,7 +45348,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4495
+  /* "pywrapfst.pyx":4509
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -45214,12 +45357,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4495, __pyx_L1_error)
+    __PYX_ERR(0, 4509, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4486
+  /* "pywrapfst.pyx":4500
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45263,7 +45406,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4486, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4500, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45280,7 +45423,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4497
+/* "pywrapfst.pyx":4511
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45310,7 +45453,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4497, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4511, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45326,10 +45469,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4497, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4511, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4497, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4511, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45348,7 +45491,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4498
+  /* "pywrapfst.pyx":4512
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
@@ -45357,12 +45500,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4498, __pyx_L1_error)
+    __PYX_ERR(0, 4512, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4497
+  /* "pywrapfst.pyx":4511
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45405,7 +45548,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4497, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4511, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45422,7 +45565,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4500
+/* "pywrapfst.pyx":4514
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -45453,7 +45596,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4500, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4514, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_15find)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45469,10 +45612,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_key) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4500, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4514, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4500, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4514, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45491,7 +45634,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4513
+  /* "pywrapfst.pyx":4527
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
@@ -45500,13 +45643,13 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4513, __pyx_L1_error)
+    __PYX_ERR(0, 4527, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4513, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4527, __pyx_L1_error)
   __pyx_r = __pyx_v_self->_reader.get()->Find(__pyx_t_6);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4500
+  /* "pywrapfst.pyx":4514
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -45550,7 +45693,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4500, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45567,7 +45710,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4515
+/* "pywrapfst.pyx":4529
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -45596,7 +45739,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4515, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4529, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_17get_fst)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -45613,10 +45756,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4515, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4529, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4515, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4529, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45635,7 +45778,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
     #endif
   }
 
-  /* "pywrapfst.pyx":4524
+  /* "pywrapfst.pyx":4538
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
@@ -45645,15 +45788,15 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4524, __pyx_L1_error)
+    __PYX_ERR(0, 4538, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4524, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4538, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4515
+  /* "pywrapfst.pyx":4529
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -45698,7 +45841,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_9FarReader_get_fst(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4515, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_9FarReader_get_fst(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4529, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45715,7 +45858,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4526
+/* "pywrapfst.pyx":4540
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -45745,7 +45888,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4526, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4540, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_19get_key)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45761,10 +45904,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4526, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4540, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4526, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4540, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45783,7 +45926,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":4535
+  /* "pywrapfst.pyx":4549
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -45792,12 +45935,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4535, __pyx_L1_error)
+    __PYX_ERR(0, 4549, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4526
+  /* "pywrapfst.pyx":4540
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -45841,7 +45984,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4526, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4540, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45858,7 +46001,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4537
+/* "pywrapfst.pyx":4551
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45886,7 +46029,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4537, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4551, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_21next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45902,7 +46045,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4537, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4551, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -45922,7 +46065,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4543
+  /* "pywrapfst.pyx":4557
  *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
@@ -45931,11 +46074,11 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4543, __pyx_L1_error)
+    __PYX_ERR(0, 4557, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4537
+  /* "pywrapfst.pyx":4551
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45978,7 +46121,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4537, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4551, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45995,7 +46138,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4545
+/* "pywrapfst.pyx":4559
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -46023,7 +46166,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4545, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4559, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_23reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -46039,7 +46182,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4545, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4559, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -46059,7 +46202,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4551
+  /* "pywrapfst.pyx":4565
  *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
@@ -46068,11 +46211,11 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4551, __pyx_L1_error)
+    __PYX_ERR(0, 4565, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4545
+  /* "pywrapfst.pyx":4559
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -46115,7 +46258,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4545, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4559, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46132,7 +46275,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4553
+/* "pywrapfst.pyx":4567
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -46164,7 +46307,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4554
+  /* "pywrapfst.pyx":4568
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -46173,13 +46316,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4554, __pyx_L1_error)
+    __PYX_ERR(0, 4568, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4554, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4568, __pyx_L1_error)
   __pyx_t_2 = (__pyx_v_self->_reader.get()->Find(__pyx_t_1) != 0);
   if (likely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":4555
+    /* "pywrapfst.pyx":4569
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):
  *       return self.get_fst()             # <<<<<<<<<<<<<<
@@ -46189,15 +46332,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
     __Pyx_XDECREF(__pyx_r);
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_fst");
-      __PYX_ERR(0, 4555, __pyx_L1_error)
+      __PYX_ERR(0, 4569, __pyx_L1_error)
     }
-    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4555, __pyx_L1_error)
+    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4569, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_r = __pyx_t_3;
     __pyx_t_3 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":4554
+    /* "pywrapfst.pyx":4568
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -46206,7 +46349,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4557
+  /* "pywrapfst.pyx":4571
  *       return self.get_fst()
  *     else:
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
@@ -46214,14 +46357,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  *   def __next__(self):
  */
   /*else*/ {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4557, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4571, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 4557, __pyx_L1_error)
+    __PYX_ERR(0, 4571, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4553
+  /* "pywrapfst.pyx":4567
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -46240,7 +46383,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4559
+/* "pywrapfst.pyx":4573
  *       raise KeyError(key)
  * 
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -46274,7 +46417,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":4560
+  /* "pywrapfst.pyx":4574
  * 
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -46283,12 +46426,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 4560, __pyx_L1_error)
+    __PYX_ERR(0, 4574, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":4561
+    /* "pywrapfst.pyx":4575
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -46296,9 +46439,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  *     cdef Fst _fst = self.get_fst()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 4561, __pyx_L1_error)
+    __PYX_ERR(0, 4575, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4560
+    /* "pywrapfst.pyx":4574
  * 
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -46307,7 +46450,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":4562
+  /* "pywrapfst.pyx":4576
  *     if self.done():
  *       raise StopIteration
  *     cdef string _key = self.get_key()             # <<<<<<<<<<<<<<
@@ -46316,11 +46459,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_key");
-    __PYX_ERR(0, 4562, __pyx_L1_error)
+    __PYX_ERR(0, 4576, __pyx_L1_error)
   }
   __pyx_v__key = ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_key(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":4563
+  /* "pywrapfst.pyx":4577
  *       raise StopIteration
  *     cdef string _key = self.get_key()
  *     cdef Fst _fst = self.get_fst()             # <<<<<<<<<<<<<<
@@ -46329,14 +46472,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_fst");
-    __PYX_ERR(0, 4563, __pyx_L1_error)
+    __PYX_ERR(0, 4577, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4563, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4577, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v__fst = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":4564
+  /* "pywrapfst.pyx":4578
  *     cdef string _key = self.get_key()
  *     cdef Fst _fst = self.get_fst()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -46345,11 +46488,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 4564, __pyx_L1_error)
+    __PYX_ERR(0, 4578, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":4565
+  /* "pywrapfst.pyx":4579
  *     cdef Fst _fst = self.get_fst()
  *     self.next()
  *     return (_key, _fst)             # <<<<<<<<<<<<<<
@@ -46357,9 +46500,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
  *   # This just registers this class as a possible iterator.
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4565, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4565, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
@@ -46371,7 +46514,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4559
+  /* "pywrapfst.pyx":4573
  *       raise KeyError(key)
  * 
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -46392,7 +46535,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4568
+/* "pywrapfst.pyx":4582
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -46418,7 +46561,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__iter__(struct __pyx_obj_9pyw
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":4569
+  /* "pywrapfst.pyx":4583
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -46430,7 +46573,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__iter__(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4568
+  /* "pywrapfst.pyx":4582
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -46558,7 +46701,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_32__setstate_cython__(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4592
+/* "pywrapfst.pyx":4606
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -46592,32 +46735,32 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4593
+  /* "pywrapfst.pyx":4607
  * 
  *   def __init__(self):
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4607, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4607, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4607, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4607, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4607, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 4593, __pyx_L1_error)
+  __PYX_ERR(0, 4607, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4592
+  /* "pywrapfst.pyx":4606
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -46635,7 +46778,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4595
+/* "pywrapfst.pyx":4609
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -46669,7 +46812,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4596
+  /* "pywrapfst.pyx":4610
  * 
  *   def __repr__(self):
  *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
@@ -46677,7 +46820,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4596, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4610, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -46687,9 +46830,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4596, __pyx_L1_error)
+    __PYX_ERR(0, 4610, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4596, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4610, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
   __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
@@ -46700,9 +46843,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_2 += 16;
   __Pyx_GIVEREF(__pyx_kp_u_FarWriter_at_0x);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_FarWriter_at_0x);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4596, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4610, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4596, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4610, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -46714,14 +46857,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__3);
   PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4596, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4610, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4595
+  /* "pywrapfst.pyx":4609
  *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -46742,7 +46885,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4599
+/* "pywrapfst.pyx":4613
  * 
  *   @classmethod
  *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
@@ -46800,7 +46943,7 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4599, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4613, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -46819,7 +46962,7 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4599, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4613, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46851,46 +46994,46 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4622
+  /* "pywrapfst.pyx":4636
  *     cdef unique_ptr[fst.FarWriterClass] _tfar
- *     _tfar.reset(fst.FarWriterClass.Create(
+ *     _tfar = fst.FarWriterClass.Create(
  *         path_tostring(source),             # <<<<<<<<<<<<<<
  *         tostring(arc_type),
- *         _get_far_type(tostring(far_type))))
+ *         _get_far_type(tostring(far_type)))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4622, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4636, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4623
- *     _tfar.reset(fst.FarWriterClass.Create(
+  /* "pywrapfst.pyx":4637
+ *     _tfar = fst.FarWriterClass.Create(
  *         path_tostring(source),
  *         tostring(arc_type),             # <<<<<<<<<<<<<<
- *         _get_far_type(tostring(far_type))))
+ *         _get_far_type(tostring(far_type)))
  *     if _tfar.get() == NULL:
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4623, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4637, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4624
+  /* "pywrapfst.pyx":4638
  *         path_tostring(source),
  *         tostring(arc_type),
- *         _get_far_type(tostring(far_type))))             # <<<<<<<<<<<<<<
+ *         _get_far_type(tostring(far_type)))             # <<<<<<<<<<<<<<
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Open failed: {source!r}")
  */
-  __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4624, __pyx_L1_error)
-  __pyx_t_4 = __pyx_f_9pywrapfst__get_far_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4624, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4638, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_9pywrapfst__get_far_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4638, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4621
+  /* "pywrapfst.pyx":4635
  *     """
  *     cdef unique_ptr[fst.FarWriterClass] _tfar
- *     _tfar.reset(fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
+ *     _tfar = fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
  *         path_tostring(source),
  *         tostring(arc_type),
  */
-  __pyx_v__tfar.reset(fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_t_4));
+  __pyx_v__tfar = fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_t_4);
 
-  /* "pywrapfst.pyx":4625
+  /* "pywrapfst.pyx":4639
  *         tostring(arc_type),
- *         _get_far_type(tostring(far_type))))
+ *         _get_far_type(tostring(far_type)))
  *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstIOError(f"Open failed: {source!r}")
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
@@ -46898,18 +47041,18 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_t_5 = ((__pyx_v__tfar.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4626
- *         _get_far_type(tostring(far_type))))
+    /* "pywrapfst.pyx":4640
+ *         _get_far_type(tostring(far_type)))
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Open failed: {source!r}")             # <<<<<<<<<<<<<<
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  *     writer._writer = move(_tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4626, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4640, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4626, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4640, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Open_failed, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4626, __pyx_L1_error)
+    __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Open_failed, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4640, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_9);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_t_8 = NULL;
@@ -46925,35 +47068,35 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_9) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_9);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
     __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4626, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4640, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_Raise(__pyx_t_6, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __PYX_ERR(0, 4626, __pyx_L1_error)
+    __PYX_ERR(0, 4640, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4625
+    /* "pywrapfst.pyx":4639
  *         tostring(arc_type),
- *         _get_far_type(tostring(far_type))))
+ *         _get_far_type(tostring(far_type)))
  *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstIOError(f"Open failed: {source!r}")
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  */
   }
 
-  /* "pywrapfst.pyx":4627
+  /* "pywrapfst.pyx":4641
  *     if _tfar.get() == NULL:
  *       raise FstIOError(f"Open failed: {source!r}")
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)             # <<<<<<<<<<<<<<
  *     writer._writer = move(_tfar)
  *     return writer
  */
-  __pyx_t_6 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4627, __pyx_L1_error)
+  __pyx_t_6 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4641, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_6));
   __pyx_v_writer = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_6);
   __pyx_t_6 = 0;
 
-  /* "pywrapfst.pyx":4628
+  /* "pywrapfst.pyx":4642
  *       raise FstIOError(f"Open failed: {source!r}")
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  *     writer._writer = move(_tfar)             # <<<<<<<<<<<<<<
@@ -46962,11 +47105,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   if (unlikely(((PyObject *)__pyx_v_writer) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4628, __pyx_L1_error)
+    __PYX_ERR(0, 4642, __pyx_L1_error)
   }
   __pyx_v_writer->_writer = fst::move<std::unique_ptr<fst::script::FarWriterClass> >(__pyx_v__tfar);
 
-  /* "pywrapfst.pyx":4629
+  /* "pywrapfst.pyx":4643
  *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  *     writer._writer = move(_tfar)
  *     return writer             # <<<<<<<<<<<<<<
@@ -46978,7 +47121,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_r = ((PyObject *)__pyx_v_writer);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4599
+  /* "pywrapfst.pyx":4613
  * 
  *   @classmethod
  *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
@@ -47001,7 +47144,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4633
+/* "pywrapfst.pyx":4647
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -47016,7 +47159,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("close", 0);
 
-  /* "pywrapfst.pyx":4634
+  /* "pywrapfst.pyx":4648
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
@@ -47025,11 +47168,11 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4634, __pyx_L1_error)
+    __PYX_ERR(0, 4648, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4633
+  /* "pywrapfst.pyx":4647
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -47045,7 +47188,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4636
+/* "pywrapfst.pyx":4650
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -47077,7 +47220,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4636, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4650, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_7add)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -47096,7 +47239,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_key, ((PyObject *)__pyx_v_ifst)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4636, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4650, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -47104,13 +47247,13 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_key, ((PyObject *)__pyx_v_ifst)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4636, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4650, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4636, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4650, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           if (__pyx_t_4) {
             __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -47121,7 +47264,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
           __Pyx_INCREF(((PyObject *)__pyx_v_ifst));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_ifst));
           PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, ((PyObject *)__pyx_v_ifst));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4636, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4650, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -47143,7 +47286,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     #endif
   }
 
-  /* "pywrapfst.pyx":4654
+  /* "pywrapfst.pyx":4668
  *     # Failure here results from passing an FST with a different arc type than
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):             # <<<<<<<<<<<<<<
@@ -47152,24 +47295,24 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4654, __pyx_L1_error)
+    __PYX_ERR(0, 4668, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4654, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4668, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4654, __pyx_L1_error)
+    __PYX_ERR(0, 4668, __pyx_L1_error)
   }
   __pyx_t_8 = ((!(__pyx_v_self->_writer.get()->Add(__pyx_t_7, (*__pyx_v_ifst->_fst)) != 0)) != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "pywrapfst.pyx":4655
+    /* "pywrapfst.pyx":4669
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):
  *       raise FstOpError("Incompatible or invalid arc type")             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4655, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4669, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -47183,14 +47326,14 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Incompatible_or_invalid_arc_type);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4655, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4669, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4655, __pyx_L1_error)
+    __PYX_ERR(0, 4669, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4654
+    /* "pywrapfst.pyx":4668
  *     # Failure here results from passing an FST with a different arc type than
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):             # <<<<<<<<<<<<<<
@@ -47199,7 +47342,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4636
+  /* "pywrapfst.pyx":4650
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -47255,11 +47398,11 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4636, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4650, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4636, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4650, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -47272,13 +47415,13 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4636, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4650, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.add", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4636, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4650, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_6add(((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_v_self), __pyx_v_key, __pyx_v_ifst);
 
   /* function exit code */
@@ -47299,8 +47442,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_9FarWriter_add(__pyx_v_self, __pyx_v_key, __pyx_v_ifst, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4636, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4636, __pyx_L1_error)
+  __pyx_f_9pywrapfst_9FarWriter_add(__pyx_v_self, __pyx_v_key, __pyx_v_ifst, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4650, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4650, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47317,7 +47460,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4657
+/* "pywrapfst.pyx":4671
  *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -47347,7 +47490,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4657, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4671, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -47363,10 +47506,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4657, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4671, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4657, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4671, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -47385,7 +47528,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4663
+  /* "pywrapfst.pyx":4677
  *     Returns a string indicating the arc type.
  *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
@@ -47394,12 +47537,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4663, __pyx_L1_error)
+    __PYX_ERR(0, 4677, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4657
+  /* "pywrapfst.pyx":4671
  *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -47443,7 +47586,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4657, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4671, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47460,7 +47603,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4665
+/* "pywrapfst.pyx":4679
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -47490,7 +47633,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4665, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4679, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -47506,10 +47649,10 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4665, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4679, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4665, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4679, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -47528,7 +47671,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     #endif
   }
 
-  /* "pywrapfst.pyx":4674
+  /* "pywrapfst.pyx":4688
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -47537,12 +47680,12 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4674, __pyx_L1_error)
+    __PYX_ERR(0, 4688, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4665
+  /* "pywrapfst.pyx":4679
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -47586,7 +47729,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarWriter_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4665, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarWriter_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4679, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47603,7 +47746,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4676
+/* "pywrapfst.pyx":4690
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -47633,7 +47776,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4676, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4690, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -47649,10 +47792,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4676, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4690, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4676, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4690, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -47671,7 +47814,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4682
+  /* "pywrapfst.pyx":4696
  *     Returns a string indicating the FAR type.
  *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
@@ -47680,12 +47823,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4682, __pyx_L1_error)
+    __PYX_ERR(0, 4696, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4676
+  /* "pywrapfst.pyx":4690
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -47729,7 +47872,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4676, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4690, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47746,7 +47889,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4685
+/* "pywrapfst.pyx":4699
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
@@ -47763,7 +47906,7 @@ static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self,
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst_Fst, 1, "fst", 0))) __PYX_ERR(0, 4685, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst_Fst, 1, "fst", 0))) __PYX_ERR(0, 4699, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_v_self), ((PyObject *)__pyx_v_key), ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_fst));
 
   /* function exit code */
@@ -47783,7 +47926,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4686
+  /* "pywrapfst.pyx":4700
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
@@ -47792,11 +47935,11 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "add");
-    __PYX_ERR(0, 4686, __pyx_L1_error)
+    __PYX_ERR(0, 4700, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->add(__pyx_v_self, __pyx_v_key, __pyx_v_fst, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4686, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->add(__pyx_v_self, __pyx_v_key, __pyx_v_fst, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4700, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4685
+  /* "pywrapfst.pyx":4699
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
@@ -50035,10 +50178,10 @@ static PyTypeObject __pyx_type_9pywrapfst_Arc = {
   0, /*tp_print*/
   #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst_ArcIterator __pyx_vtable_9pywrapfst_ArcIterator;
+static struct __pyx_vtabstruct_9pywrapfst__ArcIterator __pyx_vtable_9pywrapfst__ArcIterator;
 
-static PyObject *__pyx_tp_new_9pywrapfst_ArcIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst_ArcIterator *p;
+static PyObject *__pyx_tp_new_9pywrapfst__ArcIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst__ArcIterator *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -50046,15 +50189,15 @@ static PyObject *__pyx_tp_new_9pywrapfst_ArcIterator(PyTypeObject *t, CYTHON_UNU
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst_ArcIterator *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_ArcIterator;
+  p = ((struct __pyx_obj_9pywrapfst__ArcIterator *)o);
+  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst__ArcIterator;
   new((void*)&(p->_fst)) std::shared_ptr<fst::script::FstClass> ();
   new((void*)&(p->_aiter)) std::unique_ptr<fst::script::ArcIteratorClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst_ArcIterator(PyObject *o) {
-  struct __pyx_obj_9pywrapfst_ArcIterator *p = (struct __pyx_obj_9pywrapfst_ArcIterator *)o;
+static void __pyx_tp_dealloc_9pywrapfst__ArcIterator(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__ArcIterator *p = (struct __pyx_obj_9pywrapfst__ArcIterator *)o;
   #if CYTHON_USE_TP_FINALIZE
   if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
@@ -50065,29 +50208,29 @@ static void __pyx_tp_dealloc_9pywrapfst_ArcIterator(PyObject *o) {
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_11ArcIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_11ArcIterator_7__next__(self);}
-
-static PyMethodDef __pyx_methods_9pywrapfst_ArcIterator[] = {
-  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_11ArcIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
-  {"done", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_8done},
-  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_11flags, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_10flags},
-  {"next", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_13next, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_12next},
-  {"position", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_15position, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_14position},
-  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_17reset, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_16reset},
-  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_19seek, METH_O, __pyx_doc_9pywrapfst_11ArcIterator_18seek},
-  {"set_flags", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11ArcIterator_21set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11ArcIterator_20set_flags},
-  {"value", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_23value, METH_NOARGS, __pyx_doc_9pywrapfst_11ArcIterator_22value},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_25__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_27__setstate_cython__, METH_O, 0},
+static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_12_ArcIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_12_ArcIterator_7__next__(self);}
+
+static PyMethodDef __pyx_methods_9pywrapfst__ArcIterator[] = {
+  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_12_ArcIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
+  {"done", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_8done},
+  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_11flags, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_10flags},
+  {"next", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_13next, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_12next},
+  {"position", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_15position, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_14position},
+  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_17reset, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_16reset},
+  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_19seek, METH_O, __pyx_doc_9pywrapfst_12_ArcIterator_18seek},
+  {"set_flags", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_12_ArcIterator_21set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12_ArcIterator_20set_flags},
+  {"value", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_23value, METH_NOARGS, __pyx_doc_9pywrapfst_12_ArcIterator_22value},
+  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_25__reduce_cython__, METH_NOARGS, 0},
+  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_12_ArcIterator_27__setstate_cython__, METH_O, 0},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
+static PyTypeObject __pyx_type_9pywrapfst__ArcIterator = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst.ArcIterator", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst_ArcIterator), /*tp_basicsize*/
+  "pywrapfst._ArcIterator", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__ArcIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst_ArcIterator, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__ArcIterator, /*tp_dealloc*/
   #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
   #endif
@@ -50102,7 +50245,7 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_11ArcIterator_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_12_ArcIterator_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -50113,14 +50256,14 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  ArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST.\n  ", /*tp_doc*/
+  "\n  _ArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_11ArcIterator_5__iter__, /*tp_iter*/
-  __pyx_pw_9pywrapfst_11ArcIterator_7__next__, /*tp_iternext*/
-  __pyx_methods_9pywrapfst_ArcIterator, /*tp_methods*/
+  __pyx_pw_9pywrapfst_12_ArcIterator_5__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_12_ArcIterator_7__next__, /*tp_iternext*/
+  __pyx_methods_9pywrapfst__ArcIterator, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -50128,9 +50271,9 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_11ArcIterator_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_12_ArcIterator_3__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst_ArcIterator, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__ArcIterator, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -50150,10 +50293,10 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   0, /*tp_print*/
   #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator __pyx_vtable_9pywrapfst_MutableArcIterator;
+static struct __pyx_vtabstruct_9pywrapfst__MutableArcIterator __pyx_vtable_9pywrapfst__MutableArcIterator;
 
-static PyObject *__pyx_tp_new_9pywrapfst_MutableArcIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *p;
+static PyObject *__pyx_tp_new_9pywrapfst__MutableArcIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst__MutableArcIterator *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -50161,15 +50304,15 @@ static PyObject *__pyx_tp_new_9pywrapfst_MutableArcIterator(PyTypeObject *t, CYT
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst_MutableArcIterator *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_MutableArcIterator;
+  p = ((struct __pyx_obj_9pywrapfst__MutableArcIterator *)o);
+  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst__MutableArcIterator;
   new((void*)&(p->_mfst)) std::shared_ptr<fst::script::MutableFstClass> ();
   new((void*)&(p->_aiter)) std::unique_ptr<fst::script::MutableArcIteratorClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst_MutableArcIterator(PyObject *o) {
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *p = (struct __pyx_obj_9pywrapfst_MutableArcIterator *)o;
+static void __pyx_tp_dealloc_9pywrapfst__MutableArcIterator(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__MutableArcIterator *p = (struct __pyx_obj_9pywrapfst__MutableArcIterator *)o;
   #if CYTHON_USE_TP_FINALIZE
   if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
@@ -50180,27 +50323,30 @@ static void __pyx_tp_dealloc_9pywrapfst_MutableArcIterator(PyObject *o) {
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst_MutableArcIterator[] = {
-  {"done", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_8done, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_7done},
-  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_10flags, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_9flags},
-  {"next", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_12next, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_11next},
-  {"position", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_14position, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_13position},
-  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_16reset, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_15reset},
-  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_18seek, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_17seek},
-  {"set_flags", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_18MutableArcIterator_19set_flags},
-  {"set_value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_21set_value},
-  {"value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_24value, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_23value},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_26__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_28__setstate_cython__, METH_O, 0},
+static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__(self);}
+
+static PyMethodDef __pyx_methods_9pywrapfst__MutableArcIterator[] = {
+  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__, METH_NOARGS|METH_COEXIST, 0},
+  {"done", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_10done, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_9done},
+  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_12flags, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_11flags},
+  {"next", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_14next, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_13next},
+  {"position", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_16position, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_15position},
+  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_18reset, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_17reset},
+  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_20seek, METH_O, __pyx_doc_9pywrapfst_19_MutableArcIterator_19seek},
+  {"set_flags", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_19_MutableArcIterator_22set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_19_MutableArcIterator_21set_flags},
+  {"set_value", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_24set_value, METH_O, __pyx_doc_9pywrapfst_19_MutableArcIterator_23set_value},
+  {"value", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_26value, METH_NOARGS, __pyx_doc_9pywrapfst_19_MutableArcIterator_25value},
+  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_28__reduce_cython__, METH_NOARGS, 0},
+  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_19_MutableArcIterator_30__setstate_cython__, METH_O, 0},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
+static PyTypeObject __pyx_type_9pywrapfst__MutableArcIterator = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst.MutableArcIterator", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst_MutableArcIterator), /*tp_basicsize*/
+  "pywrapfst._MutableArcIterator", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__MutableArcIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst_MutableArcIterator, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__MutableArcIterator, /*tp_dealloc*/
   #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
   #endif
@@ -50215,7 +50361,7 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_18MutableArcIterator_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_19_MutableArcIterator_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -50226,14 +50372,14 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  MutableArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST,\n  also permitting mutation of the current arc.\n  ", /*tp_doc*/
+  "\n  _MutableArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST,\n  also permitting mutation of the current arc.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__, /*tp_iter*/
-  0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst_MutableArcIterator, /*tp_methods*/
+  __pyx_pw_9pywrapfst_19_MutableArcIterator_5__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_19_MutableArcIterator_8__next__, /*tp_iternext*/
+  __pyx_methods_9pywrapfst__MutableArcIterator, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -50241,9 +50387,9 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_19_MutableArcIterator_3__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst_MutableArcIterator, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__MutableArcIterator, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -50263,10 +50409,10 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   0, /*tp_print*/
   #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst_StateIterator __pyx_vtable_9pywrapfst_StateIterator;
+static struct __pyx_vtabstruct_9pywrapfst__StateIterator __pyx_vtable_9pywrapfst__StateIterator;
 
-static PyObject *__pyx_tp_new_9pywrapfst_StateIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst_StateIterator *p;
+static PyObject *__pyx_tp_new_9pywrapfst__StateIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst__StateIterator *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -50274,15 +50420,15 @@ static PyObject *__pyx_tp_new_9pywrapfst_StateIterator(PyTypeObject *t, CYTHON_U
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst_StateIterator *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_StateIterator;
+  p = ((struct __pyx_obj_9pywrapfst__StateIterator *)o);
+  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst__StateIterator;
   new((void*)&(p->_fst)) std::shared_ptr<fst::script::FstClass> ();
   new((void*)&(p->_siter)) std::unique_ptr<fst::script::StateIteratorClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst_StateIterator(PyObject *o) {
-  struct __pyx_obj_9pywrapfst_StateIterator *p = (struct __pyx_obj_9pywrapfst_StateIterator *)o;
+static void __pyx_tp_dealloc_9pywrapfst__StateIterator(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__StateIterator *p = (struct __pyx_obj_9pywrapfst__StateIterator *)o;
   #if CYTHON_USE_TP_FINALIZE
   if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
@@ -50293,25 +50439,25 @@ static void __pyx_tp_dealloc_9pywrapfst_StateIterator(PyObject *o) {
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_13StateIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_13StateIterator_7__next__(self);}
+static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_14_StateIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_14_StateIterator_7__next__(self);}
 
-static PyMethodDef __pyx_methods_9pywrapfst_StateIterator[] = {
-  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_13StateIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
-  {"done", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_13StateIterator_8done},
-  {"next", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_11next, METH_NOARGS, __pyx_doc_9pywrapfst_13StateIterator_10next},
-  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_13reset, METH_NOARGS, __pyx_doc_9pywrapfst_13StateIterator_12reset},
-  {"value", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_15value, METH_NOARGS, __pyx_doc_9pywrapfst_13StateIterator_14value},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_17__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_19__setstate_cython__, METH_O, 0},
+static PyMethodDef __pyx_methods_9pywrapfst__StateIterator[] = {
+  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_14_StateIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
+  {"done", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_14_StateIterator_8done},
+  {"next", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_11next, METH_NOARGS, __pyx_doc_9pywrapfst_14_StateIterator_10next},
+  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_13reset, METH_NOARGS, __pyx_doc_9pywrapfst_14_StateIterator_12reset},
+  {"value", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_15value, METH_NOARGS, __pyx_doc_9pywrapfst_14_StateIterator_14value},
+  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_17__reduce_cython__, METH_NOARGS, 0},
+  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_14_StateIterator_19__setstate_cython__, METH_O, 0},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
+static PyTypeObject __pyx_type_9pywrapfst__StateIterator = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst.StateIterator", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst_StateIterator), /*tp_basicsize*/
+  "pywrapfst._StateIterator", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__StateIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst_StateIterator, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__StateIterator, /*tp_dealloc*/
   #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
   #endif
@@ -50326,7 +50472,7 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_13StateIterator_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_14_StateIterator_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -50337,14 +50483,14 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  StateIterator(ifst)\n\n  This class is used for iterating over the states in an FST.\n  ", /*tp_doc*/
+  "\n  _StateIterator(ifst)\n\n  This class is used for iterating over the states in an FST.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_13StateIterator_5__iter__, /*tp_iter*/
-  __pyx_pw_9pywrapfst_13StateIterator_7__next__, /*tp_iternext*/
-  __pyx_methods_9pywrapfst_StateIterator, /*tp_methods*/
+  __pyx_pw_9pywrapfst_14_StateIterator_5__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_14_StateIterator_7__next__, /*tp_iternext*/
+  __pyx_methods_9pywrapfst__StateIterator, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -50352,9 +50498,9 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_13StateIterator_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_14_StateIterator_3__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst_StateIterator, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__StateIterator, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -51342,16 +51488,16 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {0, 0, 0, 0, 0, 0, 0}
 };
 static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 147, __pyx_L1_error)
-  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 157, __pyx_L1_error)
-  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 162, __pyx_L1_error)
-  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 167, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1420, __pyx_L1_error)
-  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 196, __pyx_L1_error)
-  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 425, __pyx_L1_error)
-  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 746, __pyx_L1_error)
-  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1286, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4557, __pyx_L1_error)
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 149, __pyx_L1_error)
+  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 159, __pyx_L1_error)
+  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 164, __pyx_L1_error)
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 169, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1422, __pyx_L1_error)
+  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 198, __pyx_L1_error)
+  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 427, __pyx_L1_error)
+  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 748, __pyx_L1_error)
+  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1288, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4571, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -51399,17 +51545,17 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__8);
   __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "pywrapfst.pyx":1578
+  /* "pywrapfst.pyx":1580
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_tuple__9 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __pyx_tuple__9 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__9);
   __Pyx_GIVEREF(__pyx_tuple__9);
-  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_tuple__9); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_tuple__9); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 1580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
 
@@ -51546,77 +51692,77 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__58);
   __Pyx_GIVEREF(__pyx_tuple__58);
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":516
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_tuple__59 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __pyx_tuple__59 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 516, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__59);
   __Pyx_GIVEREF(__pyx_tuple__59);
-  __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 514, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 516, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 516, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":546
+  /* "pywrapfst.pyx":548
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_tuple__61 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(0, 546, __pyx_L1_error)
+  __pyx_tuple__61 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(0, 548, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__61);
   __Pyx_GIVEREF(__pyx_tuple__61);
-  __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_times, 546, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(0, 546, __pyx_L1_error)
+  __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_times, 548, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(0, 548, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":578
+  /* "pywrapfst.pyx":580
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_tuple__63 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 578, __pyx_L1_error)
+  __pyx_tuple__63 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__63);
   __Pyx_GIVEREF(__pyx_tuple__63);
-  __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_divide, 578, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(0, 578, __pyx_L1_error)
+  __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_divide, 580, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(0, 580, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":611
+  /* "pywrapfst.pyx":613
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_tuple__65 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 611, __pyx_L1_error)
+  __pyx_tuple__65 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 613, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__65);
   __Pyx_GIVEREF(__pyx_tuple__65);
-  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 611, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 611, __pyx_L1_error)
+  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 613, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 613, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1421
+  /* "pywrapfst.pyx":1423
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1421, __pyx_L1_error)
+  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__67);
   __Pyx_GIVEREF(__pyx_tuple__67);
-  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 1421, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1421, __pyx_L1_error)
+  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 1423, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1423, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4135
+  /* "pywrapfst.pyx":4149
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__69 = PyTuple_Pack(7, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 4135, __pyx_L1_error)
+  __pyx_tuple__69 = PyTuple_Pack(7, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 4149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__69);
   __Pyx_GIVEREF(__pyx_tuple__69);
-  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(5, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4135, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 4135, __pyx_L1_error)
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(5, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4149, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 4149, __pyx_L1_error)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -51668,7 +51814,7 @@ static int __Pyx_modinit_function_export_code(void) {
   if (__Pyx_ExportFunction("_get_compose_filter", (void (*)(void))__pyx_f_9pywrapfst__get_compose_filter, "enum fst::ComposeFilter (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_determinize_type", (void (*)(void))__pyx_f_9pywrapfst__get_determinize_type, "enum fst::DeterminizeType (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_queue_type", (void (*)(void))__pyx_f_9pywrapfst__get_queue_type, "enum fst::QueueType (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_get_rand_arc_selection", (void (*)(void))__pyx_f_9pywrapfst__get_rand_arc_selection, "enum fst::script::RandArcSelection (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_get_rand_arc_selection", (void (*)(void))__pyx_f_9pywrapfst__get_rand_arc_selection, "fst::script::RandArcSelection (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_replace_label_type", (void (*)(void))__pyx_f_9pywrapfst__get_replace_label_type, "enum fst::ReplaceLabelType (std::string const &, bool)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_WeightClass_or_one", (void (*)(void))__pyx_f_9pywrapfst__get_WeightClass_or_one, "fst::script::WeightClass (std::string const &, PyObject *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_WeightClass_or_zero", (void (*)(void))__pyx_f_9pywrapfst__get_WeightClass_or_zero, "fst::script::WeightClass (std::string const &, PyObject *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -51734,16 +51880,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_Weight.to_string = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_to_string;
   __pyx_vtable_9pywrapfst_Weight.type = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_type;
   __pyx_vtable_9pywrapfst_Weight.member = (bool (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_member;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 404, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 406, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Weight.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Weight.tp_dictoffset && __pyx_type_9pywrapfst_Weight.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Weight.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 404, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Weight_2, (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 404, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 404, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 406, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Weight_2, (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 406, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 406, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Weight = &__pyx_type_9pywrapfst_Weight;
   __pyx_vtabptr_9pywrapfst_SymbolTableView = &__pyx_vtable_9pywrapfst_SymbolTableView;
   __pyx_vtable_9pywrapfst_SymbolTableView._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_15SymbolTableView__raw;
@@ -51760,43 +51906,43 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_SymbolTableView.write = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write;
   __pyx_vtable_9pywrapfst_SymbolTableView.write_text = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write_text;
   __pyx_vtable_9pywrapfst_SymbolTableView.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 731, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 733, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_SymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_SymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 731, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableView, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 731, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 733, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableView, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 733, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_SymbolTableView = &__pyx_type_9pywrapfst_SymbolTableView;
   __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView = &__pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView;
   __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
   __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_28_EncodeMapperSymbolTableView__raw;
   __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 934, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 936, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 934, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 934, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 936, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 936, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView = &__pyx_type_9pywrapfst__EncodeMapperSymbolTableView;
   __pyx_vtabptr_9pywrapfst__FstSymbolTableView = &__pyx_vtable_9pywrapfst__FstSymbolTableView;
   __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
   __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_19_FstSymbolTableView__raw;
   __pyx_type_9pywrapfst__FstSymbolTableView.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 958, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 960, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__FstSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__FstSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__FstSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__FstSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 958, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 958, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 960, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 960, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__FstSymbolTableView = &__pyx_type_9pywrapfst__FstSymbolTableView;
   __pyx_vtabptr_9pywrapfst__MutableSymbolTable = &__pyx_vtable_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
@@ -51807,53 +51953,53 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__MutableSymbolTable.add_table = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.set_name = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_set_name;
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 981, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 983, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 981, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 981, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 983, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 983, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableSymbolTable = &__pyx_type_9pywrapfst__MutableSymbolTable;
   __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView = &__pyx_vtable_9pywrapfst__MutableFstSymbolTableView;
   __pyx_vtable_9pywrapfst__MutableFstSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst__MutableFstSymbolTableView.__pyx_base._mutable_raw = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_26_MutableFstSymbolTableView__mutable_raw;
   __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1053, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1053, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1053, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableFstSymbolTableView = &__pyx_type_9pywrapfst__MutableFstSymbolTableView;
   __pyx_vtabptr_9pywrapfst_SymbolTable = &__pyx_vtable_9pywrapfst_SymbolTable;
   __pyx_vtable_9pywrapfst_SymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst_SymbolTable.__pyx_base._mutable_raw = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_11SymbolTable__mutable_raw;
   __pyx_type_9pywrapfst_SymbolTable.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1068, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1070, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_SymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTable.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_SymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1068, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1068, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1070, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1070, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_SymbolTable = &__pyx_type_9pywrapfst_SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1264, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1266, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__SymbolTableIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__SymbolTableIterator.tp_dictoffset && __pyx_type_9pywrapfst__SymbolTableIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__SymbolTableIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1264, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1264, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1266, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1266, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__SymbolTableIterator = &__pyx_type_9pywrapfst__SymbolTableIterator;
   __pyx_vtabptr_9pywrapfst_EncodeMapper = &__pyx_vtable_9pywrapfst_EncodeMapper;
   __pyx_vtable_9pywrapfst_EncodeMapper.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_arc_type;
@@ -51865,7 +52011,7 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_EncodeMapper.output_symbols = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_output_symbols;
   __pyx_vtable_9pywrapfst_EncodeMapper._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols;
   __pyx_vtable_9pywrapfst_EncodeMapper._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1296, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1298, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
   #endif
@@ -51874,7 +52020,7 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_COMPILING_IN_CPYTHON
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1296, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1298, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__.doc = __pyx_doc_9pywrapfst_12EncodeMapper_4__call__;
@@ -51882,13 +52028,13 @@ static int __Pyx_modinit_type_init_code(void) {
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1296, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1296, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1298, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1298, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_EncodeMapper = &__pyx_type_9pywrapfst_EncodeMapper;
   __pyx_vtabptr_9pywrapfst_Fst = &__pyx_vtable_9pywrapfst_Fst;
   __pyx_vtable_9pywrapfst_Fst._local_render_svg = (std::string (*)(std::string const &))__pyx_f_9pywrapfst_3Fst__local_render_svg;
   __pyx_vtable_9pywrapfst_Fst.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_arc_type;
-  __pyx_vtable_9pywrapfst_Fst.arcs = (struct __pyx_obj_9pywrapfst_ArcIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_arcs;
+  __pyx_vtable_9pywrapfst_Fst.arcs = (struct __pyx_obj_9pywrapfst__ArcIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_arcs;
   __pyx_vtable_9pywrapfst_Fst.copy = (struct __pyx_obj_9pywrapfst_Fst *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_copy;
   __pyx_vtable_9pywrapfst_Fst.draw = (void (*)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args))__pyx_f_9pywrapfst_3Fst_draw;
   __pyx_vtable_9pywrapfst_Fst.final = (struct __pyx_obj_9pywrapfst_Weight *(*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_final;
@@ -51900,20 +52046,20 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_Fst.output_symbols = (struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_output_symbols;
   __pyx_vtable_9pywrapfst_Fst.print = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args))__pyx_f_9pywrapfst_3Fst_print;
   __pyx_vtable_9pywrapfst_Fst.start = (int64 (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_start;
-  __pyx_vtable_9pywrapfst_Fst.states = (struct __pyx_obj_9pywrapfst_StateIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_states;
+  __pyx_vtable_9pywrapfst_Fst.states = (struct __pyx_obj_9pywrapfst__StateIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_states;
   __pyx_vtable_9pywrapfst_Fst.verify = (bool (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_verify;
   __pyx_vtable_9pywrapfst_Fst.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_weight_type;
   __pyx_vtable_9pywrapfst_Fst.write = (void (*)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_write;
   __pyx_vtable_9pywrapfst_Fst.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1563, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1565, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Fst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Fst.tp_dictoffset && __pyx_type_9pywrapfst_Fst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Fst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Fst.tp_dict, __pyx_vtabptr_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1563, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1563, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Fst.tp_dict, __pyx_vtabptr_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1565, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1565, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Fst = &__pyx_type_9pywrapfst_Fst;
   __pyx_vtabptr_9pywrapfst_MutableFst = &__pyx_vtable_9pywrapfst_MutableFst;
   __pyx_vtable_9pywrapfst_MutableFst.__pyx_base = *__pyx_vtabptr_9pywrapfst_Fst;
@@ -51931,7 +52077,7 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableFst._encode = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *))__pyx_f_9pywrapfst_10MutableFst__encode;
   __pyx_vtable_9pywrapfst_MutableFst._invert = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__invert;
   __pyx_vtable_9pywrapfst_MutableFst._minimize = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__minimize;
-  __pyx_vtable_9pywrapfst_MutableFst.mutable_arcs = (struct __pyx_obj_9pywrapfst_MutableArcIterator *(*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_mutable_arcs;
+  __pyx_vtable_9pywrapfst_MutableFst.mutable_arcs = (struct __pyx_obj_9pywrapfst__MutableArcIterator *(*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_mutable_arcs;
   __pyx_vtable_9pywrapfst_MutableFst.num_states = (int64 (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_num_states;
   __pyx_vtable_9pywrapfst_MutableFst._project = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *))__pyx_f_9pywrapfst_10MutableFst__project;
   __pyx_vtable_9pywrapfst_MutableFst._prune = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__prune;
@@ -51948,112 +52094,112 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableFst._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_10MutableFst__set_output_symbols;
   __pyx_vtable_9pywrapfst_MutableFst._topsort = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__topsort;
   __pyx_type_9pywrapfst_MutableFst.tp_base = __pyx_ptype_9pywrapfst_Fst;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2028, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2030, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_MutableFst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_MutableFst.tp_dictoffset && __pyx_type_9pywrapfst_MutableFst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_MutableFst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2028, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2028, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2030, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2030, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_MutableFst = &__pyx_type_9pywrapfst_MutableFst;
   __pyx_vtabptr_9pywrapfst_VectorFst = &__pyx_vtable_9pywrapfst_VectorFst;
   __pyx_vtable_9pywrapfst_VectorFst.__pyx_base = *__pyx_vtabptr_9pywrapfst_MutableFst;
   __pyx_type_9pywrapfst_VectorFst.tp_base = __pyx_ptype_9pywrapfst_MutableFst;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2890, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2892, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_VectorFst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_VectorFst.tp_dictoffset && __pyx_type_9pywrapfst_VectorFst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_VectorFst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_VectorFst.tp_dict, __pyx_vtabptr_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2890, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_VectorFst, (PyObject *)&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2890, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_VectorFst.tp_dict, __pyx_vtabptr_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2892, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_VectorFst, (PyObject *)&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2892, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_VectorFst = &__pyx_type_9pywrapfst_VectorFst;
   __pyx_vtabptr_9pywrapfst_Arc = &__pyx_vtable_9pywrapfst_Arc;
   __pyx_vtable_9pywrapfst_Arc.copy = (struct __pyx_obj_9pywrapfst_Arc *(*)(struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Arc_copy;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3073, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3075, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Arc.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Arc.tp_dictoffset && __pyx_type_9pywrapfst_Arc.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Arc.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3073, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3073, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3073, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3075, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3075, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3075, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Arc = &__pyx_type_9pywrapfst_Arc;
-  __pyx_vtabptr_9pywrapfst_ArcIterator = &__pyx_vtable_9pywrapfst_ArcIterator;
-  __pyx_vtable_9pywrapfst_ArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_done;
-  __pyx_vtable_9pywrapfst_ArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_flags;
-  __pyx_vtable_9pywrapfst_ArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_next;
-  __pyx_vtable_9pywrapfst_ArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_position;
-  __pyx_vtable_9pywrapfst_ArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_reset;
-  __pyx_vtable_9pywrapfst_ArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_seek;
-  __pyx_vtable_9pywrapfst_ArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_set_flags;
-  __pyx_vtable_9pywrapfst_ArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3140, __pyx_L1_error)
+  __pyx_vtabptr_9pywrapfst__ArcIterator = &__pyx_vtable_9pywrapfst__ArcIterator;
+  __pyx_vtable_9pywrapfst__ArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_done;
+  __pyx_vtable_9pywrapfst__ArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_flags;
+  __pyx_vtable_9pywrapfst__ArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_next;
+  __pyx_vtable_9pywrapfst__ArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_position;
+  __pyx_vtable_9pywrapfst__ArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_reset;
+  __pyx_vtable_9pywrapfst__ArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_seek;
+  __pyx_vtable_9pywrapfst__ArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst__ArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_set_flags;
+  __pyx_vtable_9pywrapfst__ArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst__ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_ArcIterator_value;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__ArcIterator) < 0) __PYX_ERR(0, 3145, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst_ArcIterator.tp_print = 0;
-  #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_ArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_ArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst_ArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
-  }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3140, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3140, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3140, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst_ArcIterator = &__pyx_type_9pywrapfst_ArcIterator;
-  __pyx_vtabptr_9pywrapfst_MutableArcIterator = &__pyx_vtable_9pywrapfst_MutableArcIterator;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_done;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_flags;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_next;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_position;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_reset;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_seek;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_flags;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.set_value = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_value;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3251, __pyx_L1_error)
+  __pyx_type_9pywrapfst__ArcIterator.tp_print = 0;
+  #endif
+  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__ArcIterator.tp_dictoffset && __pyx_type_9pywrapfst__ArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
+    __pyx_type_9pywrapfst__ArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  }
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst__ArcIterator) < 0) __PYX_ERR(0, 3145, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst__ArcIterator) < 0) __PYX_ERR(0, 3145, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__ArcIterator) < 0) __PYX_ERR(0, 3145, __pyx_L1_error)
+  __pyx_ptype_9pywrapfst__ArcIterator = &__pyx_type_9pywrapfst__ArcIterator;
+  __pyx_vtabptr_9pywrapfst__MutableArcIterator = &__pyx_vtable_9pywrapfst__MutableArcIterator;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_done;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_flags;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_next;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_position;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_reset;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_seek;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_set_flags;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.set_value = (void (*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_set_value;
+  __pyx_vtable_9pywrapfst__MutableArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst__MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableArcIterator_value;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableArcIterator) < 0) __PYX_ERR(0, 3256, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst_MutableArcIterator.tp_print = 0;
-  #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_MutableArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
-  }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3251, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3251, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3251, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst_MutableArcIterator = &__pyx_type_9pywrapfst_MutableArcIterator;
-  __pyx_vtabptr_9pywrapfst_StateIterator = &__pyx_vtable_9pywrapfst_StateIterator;
-  __pyx_vtable_9pywrapfst_StateIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_done;
-  __pyx_vtable_9pywrapfst_StateIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_next;
-  __pyx_vtable_9pywrapfst_StateIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_reset;
-  __pyx_vtable_9pywrapfst_StateIterator.value = (int64 (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3371, __pyx_L1_error)
+  __pyx_type_9pywrapfst__MutableArcIterator.tp_print = 0;
+  #endif
+  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableArcIterator.tp_dictoffset && __pyx_type_9pywrapfst__MutableArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
+    __pyx_type_9pywrapfst__MutableArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  }
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst__MutableArcIterator) < 0) __PYX_ERR(0, 3256, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst__MutableArcIterator) < 0) __PYX_ERR(0, 3256, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__MutableArcIterator) < 0) __PYX_ERR(0, 3256, __pyx_L1_error)
+  __pyx_ptype_9pywrapfst__MutableArcIterator = &__pyx_type_9pywrapfst__MutableArcIterator;
+  __pyx_vtabptr_9pywrapfst__StateIterator = &__pyx_vtable_9pywrapfst__StateIterator;
+  __pyx_vtable_9pywrapfst__StateIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_14_StateIterator_done;
+  __pyx_vtable_9pywrapfst__StateIterator.next = (void (*)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_14_StateIterator_next;
+  __pyx_vtable_9pywrapfst__StateIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_14_StateIterator_reset;
+  __pyx_vtable_9pywrapfst__StateIterator.value = (int64 (*)(struct __pyx_obj_9pywrapfst__StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_14_StateIterator_value;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__StateIterator) < 0) __PYX_ERR(0, 3384, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst_StateIterator.tp_print = 0;
+  __pyx_type_9pywrapfst__StateIterator.tp_print = 0;
   #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_StateIterator.tp_dictoffset && __pyx_type_9pywrapfst_StateIterator.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst_StateIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__StateIterator.tp_dictoffset && __pyx_type_9pywrapfst__StateIterator.tp_getattro == PyObject_GenericGetAttr)) {
+    __pyx_type_9pywrapfst__StateIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3371, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3371, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3371, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst_StateIterator = &__pyx_type_9pywrapfst_StateIterator;
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst__StateIterator) < 0) __PYX_ERR(0, 3384, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst__StateIterator) < 0) __PYX_ERR(0, 3384, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__StateIterator) < 0) __PYX_ERR(0, 3384, __pyx_L1_error)
+  __pyx_ptype_9pywrapfst__StateIterator = &__pyx_type_9pywrapfst__StateIterator;
   __pyx_vtabptr_9pywrapfst_Compiler = &__pyx_vtable_9pywrapfst_Compiler;
   __pyx_vtable_9pywrapfst_Compiler.compile = (struct __pyx_obj_9pywrapfst_Fst *(*)(struct __pyx_obj_9pywrapfst_Compiler *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_8Compiler_compile;
   __pyx_vtable_9pywrapfst_Compiler.write = (void (*)(struct __pyx_obj_9pywrapfst_Compiler *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_8Compiler_write;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4280, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4294, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Compiler.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Compiler.tp_dictoffset && __pyx_type_9pywrapfst_Compiler.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Compiler.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4280, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4280, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4280, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4294, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4294, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4294, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Compiler = &__pyx_type_9pywrapfst_Compiler;
   __pyx_vtabptr_9pywrapfst_FarReader = &__pyx_vtable_9pywrapfst_FarReader;
   __pyx_vtable_9pywrapfst_FarReader.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_arc_type;
@@ -52065,16 +52211,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarReader.get_key = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_get_key;
   __pyx_vtable_9pywrapfst_FarReader.next = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_next;
   __pyx_vtable_9pywrapfst_FarReader.reset = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_reset;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4417, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4431, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarReader.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarReader.tp_dictoffset && __pyx_type_9pywrapfst_FarReader.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarReader.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4417, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4417, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4417, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4431, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4431, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4431, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarReader = &__pyx_type_9pywrapfst_FarReader;
   __pyx_vtabptr_9pywrapfst_FarWriter = &__pyx_vtable_9pywrapfst_FarWriter;
   __pyx_vtable_9pywrapfst_FarWriter.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_arc_type;
@@ -52082,18 +52228,18 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarWriter.add = (void (*)(struct __pyx_obj_9pywrapfst_FarWriter *, PyObject *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_add;
   __pyx_vtable_9pywrapfst_FarWriter.error = (bool (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_error;
   __pyx_vtable_9pywrapfst_FarWriter.far_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_far_type;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4572, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4586, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarWriter.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarWriter.tp_dictoffset && __pyx_type_9pywrapfst_FarWriter.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarWriter.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4572, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4572, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4572, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4586, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4586, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4586, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarWriter = &__pyx_type_9pywrapfst_FarWriter;
-  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3271, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3276, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_print = 0;
   #endif
@@ -52341,232 +52487,232 @@ if (!__Pyx_RefNanny) {
   if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   #endif
 
-  /* "pywrapfst.pyx":99
+  /* "pywrapfst.pyx":101
  * 
  * # Python imports.
  * import logging             # <<<<<<<<<<<<<<
  * import enum
  * import numbers
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) __PYX_ERR(0, 99, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":100
+  /* "pywrapfst.pyx":102
  * # Python imports.
  * import logging
  * import enum             # <<<<<<<<<<<<<<
  * import numbers
  * import os
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_enum, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_enum, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_enum, __pyx_t_1) < 0) __PYX_ERR(0, 100, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_enum, __pyx_t_1) < 0) __PYX_ERR(0, 102, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":101
+  /* "pywrapfst.pyx":103
  * import logging
  * import enum
  * import numbers             # <<<<<<<<<<<<<<
  * import os
  * import subprocess
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numbers, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numbers, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 103, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numbers, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numbers, __pyx_t_1) < 0) __PYX_ERR(0, 103, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":102
+  /* "pywrapfst.pyx":104
  * import enum
  * import numbers
  * import os             # <<<<<<<<<<<<<<
  * import subprocess
  * import sys
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) __PYX_ERR(0, 102, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) __PYX_ERR(0, 104, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":103
+  /* "pywrapfst.pyx":105
  * import numbers
  * import os
  * import subprocess             # <<<<<<<<<<<<<<
  * import sys
  * 
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 103, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 105, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_subprocess, __pyx_t_1) < 0) __PYX_ERR(0, 103, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_subprocess, __pyx_t_1) < 0) __PYX_ERR(0, 105, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":104
+  /* "pywrapfst.pyx":106
  * import os
  * import subprocess
  * import sys             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) __PYX_ERR(0, 104, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) __PYX_ERR(0, 106, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":111
+  /* "pywrapfst.pyx":113
  * # These defintions only ensure that these are defined to avoid attribute errors,
  * # but don't actually contain the type definitions. Those are in _pywrapfst.pyi.
  * import typing             # <<<<<<<<<<<<<<
  * 
  * ArcMapType = """typing.Literal["identity", "input_epsilon", "invert",
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 113, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_typing, __pyx_t_1) < 0) __PYX_ERR(0, 111, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_typing, __pyx_t_1) < 0) __PYX_ERR(0, 113, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":113
+  /* "pywrapfst.pyx":115
  * import typing
  * 
  * ArcMapType = """typing.Literal["identity", "input_epsilon", "invert",             # <<<<<<<<<<<<<<
  *                                "output_epsilon", "plus", "power", "quantize",
  *                                "rmweight", "superfinal", "times", "to_log",
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ArcMapType, __pyx_kp_u_typing_Literal_identity_input_ep) < 0) __PYX_ERR(0, 113, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ArcMapType, __pyx_kp_u_typing_Literal_identity_input_ep) < 0) __PYX_ERR(0, 115, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":118
+  /* "pywrapfst.pyx":120
  *                                # NOTE: Both spellings of "to_std"
  *                                "to_log64", "to_std", "to_standard"]"""
  * ComposeFilter = """typing.Literal["alt_sequence", "auto", "match", "no_match",             # <<<<<<<<<<<<<<
  *                            "null", "sequence", "trivial"]"""
  * DeterminizeType = """typing.Literal["functional", "nonfunctional",
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ComposeFilter, __pyx_kp_u_typing_Literal_alt_sequence_auto) < 0) __PYX_ERR(0, 118, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ComposeFilter, __pyx_kp_u_typing_Literal_alt_sequence_auto) < 0) __PYX_ERR(0, 120, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":120
+  /* "pywrapfst.pyx":122
  * ComposeFilter = """typing.Literal["alt_sequence", "auto", "match", "no_match",
  *                            "null", "sequence", "trivial"]"""
  * DeterminizeType = """typing.Literal["functional", "nonfunctional",             # <<<<<<<<<<<<<<
  *                                     "disambiguate"]"""
  * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DeterminizeType, __pyx_kp_u_typing_Literal_functional_nonfun) < 0) __PYX_ERR(0, 120, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DeterminizeType, __pyx_kp_u_typing_Literal_functional_nonfun) < 0) __PYX_ERR(0, 122, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":122
+  /* "pywrapfst.pyx":124
  * DeterminizeType = """typing.Literal["functional", "nonfunctional",
  *                                     "disambiguate"]"""
  * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""             # <<<<<<<<<<<<<<
  * FarType = """typing.Literal[
  *   "fst",
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DrawFloatFormat, __pyx_kp_u_typing_Literal_e_f_g) < 0) __PYX_ERR(0, 122, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DrawFloatFormat, __pyx_kp_u_typing_Literal_e_f_g) < 0) __PYX_ERR(0, 124, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":123
+  /* "pywrapfst.pyx":125
  *                                     "disambiguate"]"""
  * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""
  * FarType = """typing.Literal[             # <<<<<<<<<<<<<<
  *   "fst",
  *   "stlist",
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FarType, __pyx_kp_u_typing_Literal_fst_stlist_sttabl) < 0) __PYX_ERR(0, 123, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FarType, __pyx_kp_u_typing_Literal_fst_stlist_sttabl) < 0) __PYX_ERR(0, 125, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":129
+  /* "pywrapfst.pyx":131
  *   "default"
  * ]"""
  * ProjectType = """typing.Literal["input", "output"]"""             # <<<<<<<<<<<<<<
  * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",
  *                               "top"]"""
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ProjectType, __pyx_kp_u_typing_Literal_input_output) < 0) __PYX_ERR(0, 129, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ProjectType, __pyx_kp_u_typing_Literal_input_output) < 0) __PYX_ERR(0, 131, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":130
+  /* "pywrapfst.pyx":132
  * ]"""
  * ProjectType = """typing.Literal["input", "output"]"""
  * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",             # <<<<<<<<<<<<<<
  *                               "top"]"""
  * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_QueueType, __pyx_kp_u_typing_Literal_auto_fifo_lifo_sh) < 0) __PYX_ERR(0, 130, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_QueueType, __pyx_kp_u_typing_Literal_auto_fifo_lifo_sh) < 0) __PYX_ERR(0, 132, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":132
+  /* "pywrapfst.pyx":134
  * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",
  *                               "top"]"""
  * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""             # <<<<<<<<<<<<<<
  * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
  * SortType = """typing.Literal["ilabel", "olabel"]"""
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RandArcSelection, __pyx_kp_u_typing_Literal_uniform_log_prob) < 0) __PYX_ERR(0, 132, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RandArcSelection, __pyx_kp_u_typing_Literal_uniform_log_prob) < 0) __PYX_ERR(0, 134, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":133
+  /* "pywrapfst.pyx":135
  *                               "top"]"""
  * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
  * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""             # <<<<<<<<<<<<<<
  * SortType = """typing.Literal["ilabel", "olabel"]"""
  * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ReplaceLabelType, __pyx_kp_u_typing_Literal_neither_input_out) < 0) __PYX_ERR(0, 133, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ReplaceLabelType, __pyx_kp_u_typing_Literal_neither_input_out) < 0) __PYX_ERR(0, 135, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":134
+  /* "pywrapfst.pyx":136
  * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
  * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
  * SortType = """typing.Literal["ilabel", "olabel"]"""             # <<<<<<<<<<<<<<
  * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
  * 
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SortType, __pyx_kp_u_typing_Literal_ilabel_olabel) < 0) __PYX_ERR(0, 134, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SortType, __pyx_kp_u_typing_Literal_ilabel_olabel) < 0) __PYX_ERR(0, 136, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":135
+  /* "pywrapfst.pyx":137
  * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
  * SortType = """typing.Literal["ilabel", "olabel"]"""
  * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""             # <<<<<<<<<<<<<<
  * 
  * WeightLike = "typing.Union[Weight, typing.Union[str, int, float]]"
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StateMapType, __pyx_kp_u_typing_Literal_arc_sum_arc_uniqu) < 0) __PYX_ERR(0, 135, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StateMapType, __pyx_kp_u_typing_Literal_arc_sum_arc_uniqu) < 0) __PYX_ERR(0, 137, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":137
+  /* "pywrapfst.pyx":139
  * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
  * 
  * WeightLike = "typing.Union[Weight, typing.Union[str, int, float]]"             # <<<<<<<<<<<<<<
  * 
  * ## Custom exceptions.
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WeightLike, __pyx_kp_u_typing_Union_Weight_typing_Union) < 0) __PYX_ERR(0, 137, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WeightLike, __pyx_kp_u_typing_Union_Weight_typing_Union) < 0) __PYX_ERR(0, 139, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":142
+  /* "pywrapfst.pyx":144
  * 
  * 
  * class FstError(Exception):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
   __Pyx_GIVEREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 142, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstError, __pyx_n_s_FstError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstError, __pyx_n_s_FstError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 142, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 142, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 144, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":147
+  /* "pywrapfst.pyx":149
  * 
  * 
  * class FstArgError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 147, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -52574,28 +52720,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_ValueError);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_ValueError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstArgError, __pyx_n_s_FstArgError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstArgError, __pyx_n_s_FstArgError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstArgError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 147, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstArgError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 147, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 149, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":152
+  /* "pywrapfst.pyx":154
  * 
  * 
  * class FstBadWeightError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 152, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 152, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
@@ -52603,28 +52749,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_ValueError);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_ValueError);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 152, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstBadWeightError, __pyx_n_s_FstBadWeightError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 152, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstBadWeightError, __pyx_n_s_FstBadWeightError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstBadWeightError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 152, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstBadWeightError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 152, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 154, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":157
+  /* "pywrapfst.pyx":159
  * 
  * 
  * class FstIndexError(FstError, IndexError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 157, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 157, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -52632,28 +52778,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_IndexError);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_IndexError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 157, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstIndexError, __pyx_n_s_FstIndexError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 157, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstIndexError, __pyx_n_s_FstIndexError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstIndexError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 157, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstIndexError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIndexError, __pyx_t_4) < 0) __PYX_ERR(0, 157, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIndexError, __pyx_t_4) < 0) __PYX_ERR(0, 159, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":162
+  /* "pywrapfst.pyx":164
  * 
  * 
  * class FstIOError(FstError, IOError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 162, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
@@ -52661,28 +52807,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_IOError);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_IOError);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstIOError, __pyx_n_s_FstIOError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 162, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstIOError, __pyx_n_s_FstIOError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstIOError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 162, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstIOError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIOError, __pyx_t_4) < 0) __PYX_ERR(0, 162, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIOError, __pyx_t_4) < 0) __PYX_ERR(0, 164, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":167
+  /* "pywrapfst.pyx":169
  * 
  * 
  * class FstOpError(FstError, RuntimeError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 167, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 167, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -52690,139 +52836,139 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_RuntimeError);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_RuntimeError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 167, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstOpError, __pyx_n_s_FstOpError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstOpError, __pyx_n_s_FstOpError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstOpError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 167, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstOpError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstOpError, __pyx_t_4) < 0) __PYX_ERR(0, 167, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstOpError, __pyx_t_4) < 0) __PYX_ERR(0, 169, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":461
+  /* "pywrapfst.pyx":463
  * 
  *   @classmethod
  *   def zero(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.zero(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_zero); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 461, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_zero); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":460
+  /* "pywrapfst.pyx":462
  *   # C++ part out-of-class and then call it from within.
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def zero(cls, weight_type):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 460, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 462, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_zero, __pyx_t_1) < 0) __PYX_ERR(0, 461, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_zero, __pyx_t_1) < 0) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":470
+  /* "pywrapfst.pyx":472
  * 
  *   @classmethod
  *   def one(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.one(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_one); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_one); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 472, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":469
+  /* "pywrapfst.pyx":471
  *     return _zero(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def one(cls, weight_type):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 469, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_one, __pyx_t_2) < 0) __PYX_ERR(0, 470, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_one, __pyx_t_2) < 0) __PYX_ERR(0, 472, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":479
+  /* "pywrapfst.pyx":481
  * 
  *   @classmethod
  *   def no_weight(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.no_weight(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_no_weight); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 479, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_no_weight); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 481, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":478
+  /* "pywrapfst.pyx":480
  *     return _one(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def no_weight(cls, weight_type):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 478, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 480, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_no_weight, __pyx_t_1) < 0) __PYX_ERR(0, 479, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_no_weight, __pyx_t_1) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":516
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 516, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_1) < 0) __PYX_ERR(0, 514, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_1) < 0) __PYX_ERR(0, 516, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":546
+  /* "pywrapfst.pyx":548
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_1) < 0) __PYX_ERR(0, 546, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_1) < 0) __PYX_ERR(0, 548, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":578
+  /* "pywrapfst.pyx":580
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 578, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 580, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_1) < 0) __PYX_ERR(0, 578, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_1) < 0) __PYX_ERR(0, 580, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":611
+  /* "pywrapfst.pyx":613
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 611, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 613, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_1) < 0) __PYX_ERR(0, 611, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_1) < 0) __PYX_ERR(0, 613, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1010
+  /* "pywrapfst.pyx":1012
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
@@ -52832,180 +52978,180 @@ if (!__Pyx_RefNanny) {
   __pyx_k__6 = fst::kNoSymbol;
   __pyx_k__6 = fst::kNoSymbol;
 
-  /* "pywrapfst.pyx":1095
+  /* "pywrapfst.pyx":1097
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1095, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1097, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1094
+  /* "pywrapfst.pyx":1096
  *     return self._smart_table.get()
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1094, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1095, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1097, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1116
+  /* "pywrapfst.pyx":1118
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_text(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1116, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1118, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1115
+  /* "pywrapfst.pyx":1117
  *     return _init_SymbolTable(move(_symbols))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_text(cls, source, bool allow_negative_labels=False):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1115, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_1) < 0) __PYX_ERR(0, 1116, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_1) < 0) __PYX_ERR(0, 1118, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1142
+  /* "pywrapfst.pyx":1144
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_fst(source, input_table)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1141
+  /* "pywrapfst.pyx":1143
  *     return _init_SymbolTable(move(_symbols))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_fst(cls, source, bool input_table):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1141, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1143, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_2) < 0) __PYX_ERR(0, 1142, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_2) < 0) __PYX_ERR(0, 1144, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1399
+  /* "pywrapfst.pyx":1401
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     EncodeMapper.read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1399, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1401, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1398
+  /* "pywrapfst.pyx":1400
  *     return FstProperties(self._mapper.get().Properties(mask.value))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1398, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1400, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1399, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1401, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1421
+  /* "pywrapfst.pyx":1423
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1421, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1421, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1420
+  /* "pywrapfst.pyx":1422
  *     return _init_EncodeMapper(_mapper.release())
  * 
  *   @staticmethod             # <<<<<<<<<<<<<<
  *   def read_from_string(state):
  *     """
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1421, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1420, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1422, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1421, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1917
+  /* "pywrapfst.pyx":1919
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1917, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1919, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1916
+  /* "pywrapfst.pyx":1918
  *     return FstProperties(self._fst.get().Properties(mask.value, test))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1916, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1918, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1917, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1919, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
 
-  /* "pywrapfst.pyx":1935
+  /* "pywrapfst.pyx":1937
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1935, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1937, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1934
+  /* "pywrapfst.pyx":1936
  *     return _read_Fst(source)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_from_string(cls, state):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1934, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1936, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1935, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1937, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
 
-  /* "pywrapfst.pyx":2308
+  /* "pywrapfst.pyx":2310
  * 
  *   cdef void _minimize(self,
  *                       float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -53014,7 +53160,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__12 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2314
+  /* "pywrapfst.pyx":2316
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -53023,7 +53169,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__13 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2409
+  /* "pywrapfst.pyx":2411
  * 
  *   cdef void _prune(self,
  *                    float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -53032,7 +53178,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__14 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2410
+  /* "pywrapfst.pyx":2412
  *   cdef void _prune(self,
  *                    float delta=fst.kDelta,
  *                    int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -53041,7 +53187,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__15 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2419
+  /* "pywrapfst.pyx":2421
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -53050,7 +53196,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__16 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2420
+  /* "pywrapfst.pyx":2422
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -53059,7 +53205,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__17 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2445
+  /* "pywrapfst.pyx":2447
  * 
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -53068,7 +53214,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__18 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2454
+  /* "pywrapfst.pyx":2456
  * 
  *   def push(self,
  *            float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -53077,7 +53223,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__19 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2685
+  /* "pywrapfst.pyx":2687
  *                        bool connect=True,
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -53086,7 +53232,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__20 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2686
+  /* "pywrapfst.pyx":2688
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:             # <<<<<<<<<<<<<<
@@ -53095,7 +53241,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__21 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2703
+  /* "pywrapfst.pyx":2705
  *                 bool connect=True,
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -53104,7 +53250,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__22 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2704
+  /* "pywrapfst.pyx":2706
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
  *                 float delta=fst.kShortestDelta):             # <<<<<<<<<<<<<<
@@ -53113,776 +53259,776 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__23 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2976
+  /* "pywrapfst.pyx":2978
  * 
  * 
  * NO_LABEL = fst.kNoLabel             # <<<<<<<<<<<<<<
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol
  */
-  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2976, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2978, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_2) < 0) __PYX_ERR(0, 2976, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_2) < 0) __PYX_ERR(0, 2978, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":2979
  * 
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId             # <<<<<<<<<<<<<<
  * NO_SYMBOL = fst.kNoSymbol
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2977, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2979, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_2) < 0) __PYX_ERR(0, 2977, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_2) < 0) __PYX_ERR(0, 2979, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2978
+  /* "pywrapfst.pyx":2980
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2978, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2980, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_2) < 0) __PYX_ERR(0, 2978, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_2) < 0) __PYX_ERR(0, 2980, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2983
+  /* "pywrapfst.pyx":2985
  * ## FST properties.
  * 
  * class FstProperties(enum.Flag):             # <<<<<<<<<<<<<<
  *   EXPANDED = fst.kExpanded
  *   MUTABLE = fst.kMutable
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Flag); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Flag); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstProperties, __pyx_n_s_FstProperties, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstProperties, __pyx_n_s_FstProperties, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2984
+  /* "pywrapfst.pyx":2986
  * 
  * class FstProperties(enum.Flag):
  *   EXPANDED = fst.kExpanded             # <<<<<<<<<<<<<<
  *   MUTABLE = fst.kMutable
  *   ERROR = fst.kError
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2984, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2986, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EXPANDED, __pyx_t_4) < 0) __PYX_ERR(0, 2984, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EXPANDED, __pyx_t_4) < 0) __PYX_ERR(0, 2986, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2985
+  /* "pywrapfst.pyx":2987
  * class FstProperties(enum.Flag):
  *   EXPANDED = fst.kExpanded
  *   MUTABLE = fst.kMutable             # <<<<<<<<<<<<<<
  *   ERROR = fst.kError
  *   ACCEPTOR = fst.kAcceptor
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2985, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2987, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_MUTABLE, __pyx_t_4) < 0) __PYX_ERR(0, 2985, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_MUTABLE, __pyx_t_4) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2986
+  /* "pywrapfst.pyx":2988
  *   EXPANDED = fst.kExpanded
  *   MUTABLE = fst.kMutable
  *   ERROR = fst.kError             # <<<<<<<<<<<<<<
  *   ACCEPTOR = fst.kAcceptor
  *   NOT_ACCEPTOR = fst.kNotAcceptor
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2986, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2988, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ERROR, __pyx_t_4) < 0) __PYX_ERR(0, 2986, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ERROR, __pyx_t_4) < 0) __PYX_ERR(0, 2988, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2987
+  /* "pywrapfst.pyx":2989
  *   MUTABLE = fst.kMutable
  *   ERROR = fst.kError
  *   ACCEPTOR = fst.kAcceptor             # <<<<<<<<<<<<<<
  *   NOT_ACCEPTOR = fst.kNotAcceptor
  *   I_DETERMINISTIC = fst.kIDeterministic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2987, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2989, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACCEPTOR, __pyx_t_4) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACCEPTOR, __pyx_t_4) < 0) __PYX_ERR(0, 2989, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2988
+  /* "pywrapfst.pyx":2990
  *   ERROR = fst.kError
  *   ACCEPTOR = fst.kAcceptor
  *   NOT_ACCEPTOR = fst.kNotAcceptor             # <<<<<<<<<<<<<<
  *   I_DETERMINISTIC = fst.kIDeterministic
  *   NON_I_DETERMINISTIC = fst.kNonIDeterministic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2988, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2990, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_4) < 0) __PYX_ERR(0, 2988, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_4) < 0) __PYX_ERR(0, 2990, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2989
+  /* "pywrapfst.pyx":2991
  *   ACCEPTOR = fst.kAcceptor
  *   NOT_ACCEPTOR = fst.kNotAcceptor
  *   I_DETERMINISTIC = fst.kIDeterministic             # <<<<<<<<<<<<<<
  *   NON_I_DETERMINISTIC = fst.kNonIDeterministic
  *   O_DETERMINISTIC = fst.kODeterministic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2989, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2991, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2989, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2991, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2990
+  /* "pywrapfst.pyx":2992
  *   NOT_ACCEPTOR = fst.kNotAcceptor
  *   I_DETERMINISTIC = fst.kIDeterministic
  *   NON_I_DETERMINISTIC = fst.kNonIDeterministic             # <<<<<<<<<<<<<<
  *   O_DETERMINISTIC = fst.kODeterministic
  *   NON_O_DETERMINISTIC = fst.kNonODeterministic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2990, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2992, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2990, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2992, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2991
+  /* "pywrapfst.pyx":2993
  *   I_DETERMINISTIC = fst.kIDeterministic
  *   NON_I_DETERMINISTIC = fst.kNonIDeterministic
  *   O_DETERMINISTIC = fst.kODeterministic             # <<<<<<<<<<<<<<
  *   NON_O_DETERMINISTIC = fst.kNonODeterministic
  *   EPSILONS = fst.kEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2991, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2993, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2991, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2993, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2992
+  /* "pywrapfst.pyx":2994
  *   NON_I_DETERMINISTIC = fst.kNonIDeterministic
  *   O_DETERMINISTIC = fst.kODeterministic
  *   NON_O_DETERMINISTIC = fst.kNonODeterministic             # <<<<<<<<<<<<<<
  *   EPSILONS = fst.kEpsilons
  *   NO_EPSILONS = fst.kNoEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2992, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2994, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2992, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_4) < 0) __PYX_ERR(0, 2994, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2993
+  /* "pywrapfst.pyx":2995
  *   O_DETERMINISTIC = fst.kODeterministic
  *   NON_O_DETERMINISTIC = fst.kNonODeterministic
  *   EPSILONS = fst.kEpsilons             # <<<<<<<<<<<<<<
  *   NO_EPSILONS = fst.kNoEpsilons
  *   I_EPSILONS = fst.kIEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2993, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2995, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2993, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2994
+  /* "pywrapfst.pyx":2996
  *   NON_O_DETERMINISTIC = fst.kNonODeterministic
  *   EPSILONS = fst.kEpsilons
  *   NO_EPSILONS = fst.kNoEpsilons             # <<<<<<<<<<<<<<
  *   I_EPSILONS = fst.kIEpsilons
  *   NO_I_EPSILONS = fst.kNoIEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2994, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2996, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2994, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2996, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2995
+  /* "pywrapfst.pyx":2997
  *   EPSILONS = fst.kEpsilons
  *   NO_EPSILONS = fst.kNoEpsilons
  *   I_EPSILONS = fst.kIEpsilons             # <<<<<<<<<<<<<<
  *   NO_I_EPSILONS = fst.kNoIEpsilons
  *   O_EPSILONS = fst.kOEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2995, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2997, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2997, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2996
+  /* "pywrapfst.pyx":2998
  *   NO_EPSILONS = fst.kNoEpsilons
  *   I_EPSILONS = fst.kIEpsilons
  *   NO_I_EPSILONS = fst.kNoIEpsilons             # <<<<<<<<<<<<<<
  *   O_EPSILONS = fst.kOEpsilons
  *   NO_O_EPSILONS = fst.kNoOEpsilons
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2998, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_I_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2996, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_I_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2998, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2997
+  /* "pywrapfst.pyx":2999
  *   I_EPSILONS = fst.kIEpsilons
  *   NO_I_EPSILONS = fst.kNoIEpsilons
  *   O_EPSILONS = fst.kOEpsilons             # <<<<<<<<<<<<<<
  *   NO_O_EPSILONS = fst.kNoOEpsilons
  *   I_LABEL_SORTED = fst.kILabelSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2997, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2999, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2997, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2998
+  /* "pywrapfst.pyx":3000
  *   NO_I_EPSILONS = fst.kNoIEpsilons
  *   O_EPSILONS = fst.kOEpsilons
  *   NO_O_EPSILONS = fst.kNoOEpsilons             # <<<<<<<<<<<<<<
  *   I_LABEL_SORTED = fst.kILabelSorted
  *   NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2998, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3000, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_O_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 2998, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NO_O_EPSILONS, __pyx_t_4) < 0) __PYX_ERR(0, 3000, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2999
+  /* "pywrapfst.pyx":3001
  *   O_EPSILONS = fst.kOEpsilons
  *   NO_O_EPSILONS = fst.kNoOEpsilons
  *   I_LABEL_SORTED = fst.kILabelSorted             # <<<<<<<<<<<<<<
  *   NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  *   O_LABEL_SORTED = fst.kOLabelSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2999, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3001, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3001, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3000
+  /* "pywrapfst.pyx":3002
  *   NO_O_EPSILONS = fst.kNoOEpsilons
  *   I_LABEL_SORTED = fst.kILabelSorted
  *   NOT_I_LABEL_SORTED = fst.kNotILabelSorted             # <<<<<<<<<<<<<<
  *   O_LABEL_SORTED = fst.kOLabelSorted
  *   NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3000, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3002, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3000, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3002, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3001
+  /* "pywrapfst.pyx":3003
  *   I_LABEL_SORTED = fst.kILabelSorted
  *   NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  *   O_LABEL_SORTED = fst.kOLabelSorted             # <<<<<<<<<<<<<<
  *   NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  *   WEIGHTED = fst.kWeighted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3001, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3003, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3001, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3003, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3002
+  /* "pywrapfst.pyx":3004
  *   NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  *   O_LABEL_SORTED = fst.kOLabelSorted
  *   NOT_O_LABEL_SORTED = fst.kNotOLabelSorted             # <<<<<<<<<<<<<<
  *   WEIGHTED = fst.kWeighted
  *   UNWEIGHTED = fst.kUnweighted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3002, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3004, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3002, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3003
+  /* "pywrapfst.pyx":3005
  *   O_LABEL_SORTED = fst.kOLabelSorted
  *   NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  *   WEIGHTED = fst.kWeighted             # <<<<<<<<<<<<<<
  *   UNWEIGHTED = fst.kUnweighted
  *   CYCLIC = fst.kCyclic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3003, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3005, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHTED, __pyx_t_4) < 0) __PYX_ERR(0, 3003, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHTED, __pyx_t_4) < 0) __PYX_ERR(0, 3005, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3004
+  /* "pywrapfst.pyx":3006
  *   NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  *   WEIGHTED = fst.kWeighted
  *   UNWEIGHTED = fst.kUnweighted             # <<<<<<<<<<<<<<
  *   CYCLIC = fst.kCyclic
  *   ACYCLIC = fst.kAcyclic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3004, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3006, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_UNWEIGHTED, __pyx_t_4) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_UNWEIGHTED, __pyx_t_4) < 0) __PYX_ERR(0, 3006, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3005
+  /* "pywrapfst.pyx":3007
  *   WEIGHTED = fst.kWeighted
  *   UNWEIGHTED = fst.kUnweighted
  *   CYCLIC = fst.kCyclic             # <<<<<<<<<<<<<<
  *   ACYCLIC = fst.kAcyclic
  *   INITIAL_CYCLIC = fst.kInitialCyclic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3005, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3007, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_CYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3005, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_CYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3007, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3006
+  /* "pywrapfst.pyx":3008
  *   UNWEIGHTED = fst.kUnweighted
  *   CYCLIC = fst.kCyclic
  *   ACYCLIC = fst.kAcyclic             # <<<<<<<<<<<<<<
  *   INITIAL_CYCLIC = fst.kInitialCyclic
  *   INITIAL_ACYCLIC = fst.kInitialAcyclic
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3006, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3008, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3006, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3008, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3007
+  /* "pywrapfst.pyx":3009
  *   CYCLIC = fst.kCyclic
  *   ACYCLIC = fst.kAcyclic
  *   INITIAL_CYCLIC = fst.kInitialCyclic             # <<<<<<<<<<<<<<
  *   INITIAL_ACYCLIC = fst.kInitialAcyclic
  *   TOP_SORTED = fst.kTopSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3007, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3007, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3009, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3008
+  /* "pywrapfst.pyx":3010
  *   ACYCLIC = fst.kAcyclic
  *   INITIAL_CYCLIC = fst.kInitialCyclic
  *   INITIAL_ACYCLIC = fst.kInitialAcyclic             # <<<<<<<<<<<<<<
  *   TOP_SORTED = fst.kTopSorted
  *   NOT_TOP_SORTED = fst.kNotTopSorted
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3008, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3010, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3008, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_4) < 0) __PYX_ERR(0, 3010, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3009
+  /* "pywrapfst.pyx":3011
  *   INITIAL_CYCLIC = fst.kInitialCyclic
  *   INITIAL_ACYCLIC = fst.kInitialAcyclic
  *   TOP_SORTED = fst.kTopSorted             # <<<<<<<<<<<<<<
  *   NOT_TOP_SORTED = fst.kNotTopSorted
  *   ACCESSIBLE = fst.kAccessible
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3009, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3011, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TOP_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3009, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TOP_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3011, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3010
+  /* "pywrapfst.pyx":3012
  *   INITIAL_ACYCLIC = fst.kInitialAcyclic
  *   TOP_SORTED = fst.kTopSorted
  *   NOT_TOP_SORTED = fst.kNotTopSorted             # <<<<<<<<<<<<<<
  *   ACCESSIBLE = fst.kAccessible
  *   NOT_ACCESSIBLE = fst.kNotAccessible
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3010, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3012, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3010, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_4) < 0) __PYX_ERR(0, 3012, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3011
+  /* "pywrapfst.pyx":3013
  *   TOP_SORTED = fst.kTopSorted
  *   NOT_TOP_SORTED = fst.kNotTopSorted
  *   ACCESSIBLE = fst.kAccessible             # <<<<<<<<<<<<<<
  *   NOT_ACCESSIBLE = fst.kNotAccessible
  *   COACCESSIBLE = fst.kCoAccessible
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3011, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3013, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3011, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3013, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3012
+  /* "pywrapfst.pyx":3014
  *   NOT_TOP_SORTED = fst.kNotTopSorted
  *   ACCESSIBLE = fst.kAccessible
  *   NOT_ACCESSIBLE = fst.kNotAccessible             # <<<<<<<<<<<<<<
  *   COACCESSIBLE = fst.kCoAccessible
  *   NOT_COACCESSIBLE = fst.kNotCoAccessible
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3012, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3014, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3012, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3014, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3013
+  /* "pywrapfst.pyx":3015
  *   ACCESSIBLE = fst.kAccessible
  *   NOT_ACCESSIBLE = fst.kNotAccessible
  *   COACCESSIBLE = fst.kCoAccessible             # <<<<<<<<<<<<<<
  *   NOT_COACCESSIBLE = fst.kNotCoAccessible
  *   STRING = fst.kString
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3013, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3015, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3013, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3015, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3014
+  /* "pywrapfst.pyx":3016
  *   NOT_ACCESSIBLE = fst.kNotAccessible
  *   COACCESSIBLE = fst.kCoAccessible
  *   NOT_COACCESSIBLE = fst.kNotCoAccessible             # <<<<<<<<<<<<<<
  *   STRING = fst.kString
  *   NOT_STRING = fst.kNotString
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3014, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3016, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3014, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_4) < 0) __PYX_ERR(0, 3016, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3015
+  /* "pywrapfst.pyx":3017
  *   COACCESSIBLE = fst.kCoAccessible
  *   NOT_COACCESSIBLE = fst.kNotCoAccessible
  *   STRING = fst.kString             # <<<<<<<<<<<<<<
  *   NOT_STRING = fst.kNotString
  *   WEIGHTED_CYCLES = fst.kWeightedCycles
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3015, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3017, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_STRING, __pyx_t_4) < 0) __PYX_ERR(0, 3015, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_STRING, __pyx_t_4) < 0) __PYX_ERR(0, 3017, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3016
+  /* "pywrapfst.pyx":3018
  *   NOT_COACCESSIBLE = fst.kNotCoAccessible
  *   STRING = fst.kString
  *   NOT_STRING = fst.kNotString             # <<<<<<<<<<<<<<
  *   WEIGHTED_CYCLES = fst.kWeightedCycles
  *   UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3018, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_STRING, __pyx_t_4) < 0) __PYX_ERR(0, 3016, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NOT_STRING, __pyx_t_4) < 0) __PYX_ERR(0, 3018, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3017
+  /* "pywrapfst.pyx":3019
  *   STRING = fst.kString
  *   NOT_STRING = fst.kNotString
  *   WEIGHTED_CYCLES = fst.kWeightedCycles             # <<<<<<<<<<<<<<
  *   UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  *   # TODO(wolfsonkin): Figure out how to keep the composite properties (all the
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3017, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3019, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_4) < 0) __PYX_ERR(0, 3017, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_4) < 0) __PYX_ERR(0, 3019, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3018
+  /* "pywrapfst.pyx":3020
  *   NOT_STRING = fst.kNotString
  *   WEIGHTED_CYCLES = fst.kWeightedCycles
  *   UNWEIGHTED_CYCLES = fst.kUnweightedCycles             # <<<<<<<<<<<<<<
  *   # TODO(wolfsonkin): Figure out how to keep the composite properties (all the
  *   # below properties) out of the `repr`, but still available as an attribute on
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3018, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3020, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_4) < 0) __PYX_ERR(0, 3018, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_4) < 0) __PYX_ERR(0, 3020, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3022
+  /* "pywrapfst.pyx":3024
  *   # below properties) out of the `repr`, but still available as an attribute on
  *   # the class. I think this could be done with `property`.
  *   NULL_PROPERTIES = fst.kNullProperties             # <<<<<<<<<<<<<<
  *   COPY_PROPERTIES = fst.kCopyProperties
  *   INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3022, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3024, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NULL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3022, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NULL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3024, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3023
+  /* "pywrapfst.pyx":3025
  *   # the class. I think this could be done with `property`.
  *   NULL_PROPERTIES = fst.kNullProperties
  *   COPY_PROPERTIES = fst.kCopyProperties             # <<<<<<<<<<<<<<
  *   INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  *   EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3023, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3025, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COPY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3023, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COPY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3025, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3024
+  /* "pywrapfst.pyx":3026
  *   NULL_PROPERTIES = fst.kNullProperties
  *   COPY_PROPERTIES = fst.kCopyProperties
  *   INTRINSIC_PROPERTIES = fst.kIntrinsicProperties             # <<<<<<<<<<<<<<
  *   EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  *   SET_START_PROPERTIES = fst.kSetStartProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3024, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3026, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3024, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3026, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3025
+  /* "pywrapfst.pyx":3027
  *   COPY_PROPERTIES = fst.kCopyProperties
  *   INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  *   EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties             # <<<<<<<<<<<<<<
  *   SET_START_PROPERTIES = fst.kSetStartProperties
  *   SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3025, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3027, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3025, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3027, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3026
+  /* "pywrapfst.pyx":3028
  *   INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  *   EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  *   SET_START_PROPERTIES = fst.kSetStartProperties             # <<<<<<<<<<<<<<
  *   SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  *   ADD_STATE_PROPERTIES = fst.kAddStateProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3026, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3028, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3026, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3028, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3027
+  /* "pywrapfst.pyx":3029
  *   EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  *   SET_START_PROPERTIES = fst.kSetStartProperties
  *   SET_FINAL_PROPERTIES = fst.kSetFinalProperties             # <<<<<<<<<<<<<<
  *   ADD_STATE_PROPERTIES = fst.kAddStateProperties
  *   ADD_ARC_PROPERTIES = fst.kAddArcProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3027, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3029, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3027, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3029, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3028
+  /* "pywrapfst.pyx":3030
  *   SET_START_PROPERTIES = fst.kSetStartProperties
  *   SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  *   ADD_STATE_PROPERTIES = fst.kAddStateProperties             # <<<<<<<<<<<<<<
  *   ADD_ARC_PROPERTIES = fst.kAddArcProperties
  *   SET_ARC_PROPERTIES = fst.kSetArcProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3028, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3030, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3028, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3030, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3029
+  /* "pywrapfst.pyx":3031
  *   SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  *   ADD_STATE_PROPERTIES = fst.kAddStateProperties
  *   ADD_ARC_PROPERTIES = fst.kAddArcProperties             # <<<<<<<<<<<<<<
  *   SET_ARC_PROPERTIES = fst.kSetArcProperties
  *   DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3029, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3031, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3029, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3031, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3030
+  /* "pywrapfst.pyx":3032
  *   ADD_STATE_PROPERTIES = fst.kAddStateProperties
  *   ADD_ARC_PROPERTIES = fst.kAddArcProperties
  *   SET_ARC_PROPERTIES = fst.kSetArcProperties             # <<<<<<<<<<<<<<
  *   DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  *   DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3030, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3032, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3030, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3032, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3031
+  /* "pywrapfst.pyx":3033
  *   ADD_ARC_PROPERTIES = fst.kAddArcProperties
  *   SET_ARC_PROPERTIES = fst.kSetArcProperties
  *   DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties             # <<<<<<<<<<<<<<
  *   DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  *   STATE_SORT_PROPERTIES = fst.kStateSortProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3031, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3033, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3031, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3033, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3032
+  /* "pywrapfst.pyx":3034
  *   SET_ARC_PROPERTIES = fst.kSetArcProperties
  *   DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  *   DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties             # <<<<<<<<<<<<<<
  *   STATE_SORT_PROPERTIES = fst.kStateSortProperties
  *   ARC_SORT_PROPERTIES = fst.kArcSortProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3032, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3034, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3032, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3034, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3033
+  /* "pywrapfst.pyx":3035
  *   DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  *   DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  *   STATE_SORT_PROPERTIES = fst.kStateSortProperties             # <<<<<<<<<<<<<<
  *   ARC_SORT_PROPERTIES = fst.kArcSortProperties
  *   I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3033, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3035, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3033, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3035, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3034
+  /* "pywrapfst.pyx":3036
  *   DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  *   STATE_SORT_PROPERTIES = fst.kStateSortProperties
  *   ARC_SORT_PROPERTIES = fst.kArcSortProperties             # <<<<<<<<<<<<<<
  *   I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  *   O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3034, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3036, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3034, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3036, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3035
+  /* "pywrapfst.pyx":3037
  *   STATE_SORT_PROPERTIES = fst.kStateSortProperties
  *   ARC_SORT_PROPERTIES = fst.kArcSortProperties
  *   I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties             # <<<<<<<<<<<<<<
  *   O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  *   WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3035, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3037, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3035, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3037, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3036
+  /* "pywrapfst.pyx":3038
  *   ARC_SORT_PROPERTIES = fst.kArcSortProperties
  *   I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  *   O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties             # <<<<<<<<<<<<<<
  *   WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  *   ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3036, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3038, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3036, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3038, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3037
+  /* "pywrapfst.pyx":3039
  *   I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  *   O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  *   WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties             # <<<<<<<<<<<<<<
  *   ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  *   RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3037, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3039, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3037, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3038
+  /* "pywrapfst.pyx":3040
  *   O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  *   WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  *   ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties             # <<<<<<<<<<<<<<
  *   RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  *   BINARY_PROPERTIES = fst.kBinaryProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3038, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3040, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3038, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3040, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3039
+  /* "pywrapfst.pyx":3041
  *   WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  *   ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  *   RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties             # <<<<<<<<<<<<<<
  *   BINARY_PROPERTIES = fst.kBinaryProperties
  *   TRINARY_PROPERTIES = fst.kTrinaryProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3039, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3041, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3041, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3040
+  /* "pywrapfst.pyx":3042
  *   ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  *   RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  *   BINARY_PROPERTIES = fst.kBinaryProperties             # <<<<<<<<<<<<<<
  *   TRINARY_PROPERTIES = fst.kTrinaryProperties
  *   POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3040, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3042, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3040, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3042, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3041
+  /* "pywrapfst.pyx":3043
  *   RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  *   BINARY_PROPERTIES = fst.kBinaryProperties
  *   TRINARY_PROPERTIES = fst.kTrinaryProperties             # <<<<<<<<<<<<<<
  *   POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  *   NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3041, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3043, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3041, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3043, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3042
+  /* "pywrapfst.pyx":3044
  *   BINARY_PROPERTIES = fst.kBinaryProperties
  *   TRINARY_PROPERTIES = fst.kTrinaryProperties
  *   POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties             # <<<<<<<<<<<<<<
  *   NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  *   FST_PROPERTIES = fst.kFstProperties
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3042, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3044, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3042, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3044, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3043
+  /* "pywrapfst.pyx":3045
  *   TRINARY_PROPERTIES = fst.kTrinaryProperties
  *   POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  *   NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties             # <<<<<<<<<<<<<<
  *   FST_PROPERTIES = fst.kFstProperties
  * 
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3043, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3045, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3043, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3045, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":3044
+  /* "pywrapfst.pyx":3046
  *   POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  *   NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  *   FST_PROPERTIES = fst.kFstProperties             # <<<<<<<<<<<<<<
  * 
  * for name, member in FstProperties.__members__.items():
  */
-  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3044, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3046, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_FST_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3044, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_FST_PROPERTIES, __pyx_t_4) < 0) __PYX_ERR(0, 3046, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2983
+  /* "pywrapfst.pyx":2985
  * ## FST properties.
  * 
  * class FstProperties(enum.Flag):             # <<<<<<<<<<<<<<
  *   EXPANDED = fst.kExpanded
  *   MUTABLE = fst.kMutable
  */
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstProperties, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2983, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstProperties, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstProperties, __pyx_t_4) < 0) __PYX_ERR(0, 2983, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstProperties, __pyx_t_4) < 0) __PYX_ERR(0, 2985, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3046
+  /* "pywrapfst.pyx":3048
  *   FST_PROPERTIES = fst.kFstProperties
  * 
  * for name, member in FstProperties.__members__.items():             # <<<<<<<<<<<<<<
@@ -53890,16 +54036,16 @@ if (!__Pyx_RefNanny) {
  * 
  */
   __pyx_t_5 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3046, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3048, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_members); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3046, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_members); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3048, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(__pyx_t_3 == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items");
-    __PYX_ERR(0, 3046, __pyx_L1_error)
+    __PYX_ERR(0, 3048, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_dict_iterator(__pyx_t_3, 0, __pyx_n_s_items, (&__pyx_t_6), (&__pyx_t_7)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3046, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_dict_iterator(__pyx_t_3, 0, __pyx_n_s_items, (&__pyx_t_6), (&__pyx_t_7)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3048, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_XDECREF(__pyx_t_2);
@@ -53908,159 +54054,159 @@ if (!__Pyx_RefNanny) {
   while (1) {
     __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_2, __pyx_t_6, &__pyx_t_5, &__pyx_t_1, &__pyx_t_3, NULL, __pyx_t_7);
     if (unlikely(__pyx_t_8 == 0)) break;
-    if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 3046, __pyx_L1_error)
+    if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 3048, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_GOTREF(__pyx_t_3);
-    if (PyDict_SetItem(__pyx_d, __pyx_n_s_name_2, __pyx_t_1) < 0) __PYX_ERR(0, 3046, __pyx_L1_error)
+    if (PyDict_SetItem(__pyx_d, __pyx_n_s_name_2, __pyx_t_1) < 0) __PYX_ERR(0, 3048, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (PyDict_SetItem(__pyx_d, __pyx_n_s_member, __pyx_t_3) < 0) __PYX_ERR(0, 3046, __pyx_L1_error)
+    if (PyDict_SetItem(__pyx_d, __pyx_n_s_member, __pyx_t_3) < 0) __PYX_ERR(0, 3048, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":3047
+    /* "pywrapfst.pyx":3049
  * 
  * for name, member in FstProperties.__members__.items():
  *   globals()[name] = member             # <<<<<<<<<<<<<<
  * 
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_member); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3047, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_member); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3049, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = __Pyx_Globals(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3047, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_Globals(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3049, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (unlikely(__pyx_t_1 == Py_None)) {
       PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
-      __PYX_ERR(0, 3047, __pyx_L1_error)
+      __PYX_ERR(0, 3049, __pyx_L1_error)
     }
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3047, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3049, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_t_4, __pyx_t_3) < 0)) __PYX_ERR(0, 3047, __pyx_L1_error)
+    if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_t_4, __pyx_t_3) < 0)) __PYX_ERR(0, 3049, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3053
+  /* "pywrapfst.pyx":3055
  * 
  * 
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue             # <<<<<<<<<<<<<<
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3053, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3055, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3053, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3055, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3054
+  /* "pywrapfst.pyx":3056
  * 
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue             # <<<<<<<<<<<<<<
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3054, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3056, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3054, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3056, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3055
+  /* "pywrapfst.pyx":3057
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue             # <<<<<<<<<<<<<<
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3055, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3057, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3055, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3057, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3056
+  /* "pywrapfst.pyx":3058
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue             # <<<<<<<<<<<<<<
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3056, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3058, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3056, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3058, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3057
+  /* "pywrapfst.pyx":3059
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache             # <<<<<<<<<<<<<<
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  * ARC_FLAGS = fst.kArcFlags
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNoCache); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3057, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNoCache); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_2) < 0) __PYX_ERR(0, 3057, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_2) < 0) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3058
+  /* "pywrapfst.pyx":3060
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags             # <<<<<<<<<<<<<<
  * ARC_FLAGS = fst.kArcFlags
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3058, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3060, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3058, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3060, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3059
+  /* "pywrapfst.pyx":3061
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  * ARC_FLAGS = fst.kArcFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3061, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3059, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3061, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3065
+  /* "pywrapfst.pyx":3067
  * 
  * 
  * ENCODE_LABELS = fst.kEncodeLabels             # <<<<<<<<<<<<<<
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3065, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3067, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_2) < 0) __PYX_ERR(0, 3065, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_2) < 0) __PYX_ERR(0, 3067, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3066
+  /* "pywrapfst.pyx":3068
  * 
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights             # <<<<<<<<<<<<<<
  * ENCODE_FLAGS = fst.kEncodeFlags
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3066, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3068, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_2) < 0) __PYX_ERR(0, 3066, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_2) < 0) __PYX_ERR(0, 3068, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3067
+  /* "pywrapfst.pyx":3069
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3067, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3069, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3067, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3069, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3439
+  /* "pywrapfst.pyx":3452
  * 
  * cdef Fst _map(Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54069,7 +54215,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__32 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3455
+  /* "pywrapfst.pyx":3469
  * 
  * cpdef Fst arcmap(Fst ifst,
  *                  float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54078,7 +54224,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3454
+  /* "pywrapfst.pyx":3468
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
@@ -54087,7 +54233,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3564
+  /* "pywrapfst.pyx":3578
  * 
  * cpdef MutableFst determinize(Fst ifst,
  *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54096,7 +54242,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__34 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3566
+  /* "pywrapfst.pyx":3580
  *                              float delta=fst.kShortestDelta,
  *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54105,7 +54251,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3564
+  /* "pywrapfst.pyx":3578
  * 
  * cpdef MutableFst determinize(Fst ifst,
  *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54114,7 +54260,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__34 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3566
+  /* "pywrapfst.pyx":3580
  *                              float delta=fst.kShortestDelta,
  *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54123,7 +54269,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3663
+  /* "pywrapfst.pyx":3677
  * 
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54132,7 +54278,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3664
+  /* "pywrapfst.pyx":3678
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54141,7 +54287,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__37 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3663
+  /* "pywrapfst.pyx":3677
  * 
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54150,7 +54296,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3664
+  /* "pywrapfst.pyx":3678
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54159,7 +54305,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__37 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3734
+  /* "pywrapfst.pyx":3748
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -54169,7 +54315,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__38 = fst::kDelta;
   __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3755
+  /* "pywrapfst.pyx":3769
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -54179,7 +54325,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__39 = fst::kDelta;
   __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3811
+  /* "pywrapfst.pyx":3825
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -54189,7 +54335,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__40 = fst::kDelta;
   __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3836
+  /* "pywrapfst.pyx":3850
  * 
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54198,7 +54344,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3837
+  /* "pywrapfst.pyx":3851
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54207,7 +54353,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__42 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3836
+  /* "pywrapfst.pyx":3850
  * 
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54216,7 +54362,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3837
+  /* "pywrapfst.pyx":3851
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54225,7 +54371,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__42 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3868
+  /* "pywrapfst.pyx":3882
  * 
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54234,7 +54380,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3867
+  /* "pywrapfst.pyx":3881
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -54243,7 +54389,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3926
+  /* "pywrapfst.pyx":3940
  *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54252,7 +54398,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__44 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3928
+  /* "pywrapfst.pyx":3942
  *                           float delta=fst.kDelta,
  *                           select="uniform",
  *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
@@ -54261,7 +54407,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3926
+  /* "pywrapfst.pyx":3940
  *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -54270,7 +54416,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__44 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3928
+  /* "pywrapfst.pyx":3942
  *                           float delta=fst.kDelta,
  *                           select="uniform",
  *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
@@ -54279,7 +54425,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3978
+  /* "pywrapfst.pyx":3992
  *                          int32 npath=1,
  *                          select="uniform",
  *                          int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
@@ -54288,7 +54434,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__46 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3975
+  /* "pywrapfst.pyx":3989
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
@@ -54297,7 +54443,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__46 = INT32_MAX;
 
-  /* "pywrapfst.pyx":4117
+  /* "pywrapfst.pyx":4131
  * cdef void _shortestdistance(Fst ifst,
  *                             vector[fst.WeightClass] *distance,
  *                             float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54306,7 +54452,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__47 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4118
+  /* "pywrapfst.pyx":4132
  *                             vector[fst.WeightClass] *distance,
  *                             float delta=fst.kShortestDelta,
  *                             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54315,7 +54461,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__48 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4136
+  /* "pywrapfst.pyx":4150
  * 
  * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54324,7 +54470,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__49 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4137
+  /* "pywrapfst.pyx":4151
  * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54333,19 +54479,19 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__50 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4135
+  /* "pywrapfst.pyx":4149
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_55shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4135, __pyx_L1_error)
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_55shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4149, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_2) < 0) __PYX_ERR(0, 4135, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_2) < 0) __PYX_ERR(0, 4149, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":4173
+  /* "pywrapfst.pyx":4187
  * 
  * cpdef MutableFst shortestpath(Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54354,7 +54500,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__51 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4175
+  /* "pywrapfst.pyx":4189
  *                               float delta=fst.kShortestDelta,
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54363,7 +54509,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__52 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4173
+  /* "pywrapfst.pyx":4187
  * 
  * cpdef MutableFst shortestpath(Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -54372,7 +54518,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__51 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4175
+  /* "pywrapfst.pyx":4189
  *                               float delta=fst.kShortestDelta,
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -54381,55 +54527,55 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__52 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4440
+  /* "pywrapfst.pyx":4454
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
  *     """
  *     FarReader.open(*sources)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4440, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4454, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4439
+  /* "pywrapfst.pyx":4453
  *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def open(cls, *sources):
  *     """
  */
-  __pyx_t_3 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4439, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4453, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_3) < 0) __PYX_ERR(0, 4440, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_3) < 0) __PYX_ERR(0, 4454, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4599
+  /* "pywrapfst.pyx":4613
  * 
  *   @classmethod
  *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __Pyx_GetNameInClass(__pyx_t_3, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4599, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_3, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4613, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":4598
+  /* "pywrapfst.pyx":4612
  *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def create(cls, source, arc_type="standard", far_type="default"):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4598, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4612, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_2) < 0) __PYX_ERR(0, 4599, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_2) < 0) __PYX_ERR(0, 4613, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4690
+  /* "pywrapfst.pyx":4704
  * 
  * # Masks fst_error_fatal in-module.
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -54439,8 +54585,8 @@ if (!__Pyx_RefNanny) {
 
   /* "pywrapfst.pyx":1
  * #cython: c_string_encoding=utf8, c_string_type=unicode, language_level=3, nonecheck=True             # <<<<<<<<<<<<<<
- * # Licensed under the Apache License, Version 2.0 (the "License");
- * # you may not use this file except in compliance with the License.
+ * # Copyright 2016-2020 Google LLC
+ * #
  */
   __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
index 3ad9b4a..09ac17a 100644 (file)
@@ -1,4 +1,18 @@
 #cython: language_level=3
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
@@ -54,7 +68,7 @@ cdef fst.WeightClass _get_WeightClass_or_zero(const string &weight_type,
                                               weight_string) except *
 
 
-cdef class Weight(object):
+cdef class Weight:
 
   cdef unique_ptr[fst.WeightClass] _weight
 
@@ -90,7 +104,7 @@ ctypedef fst.SymbolTable * SymbolTable_ptr
 ctypedef const fst.SymbolTable * const_SymbolTable_ptr
 
 
-cdef class SymbolTableView(object):
+cdef class SymbolTableView:
 
   cdef const fst.SymbolTable *_raw(self)
 
@@ -181,7 +195,7 @@ cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table)
 cpdef SymbolTable _read_SymbolTable_from_string(string state)
 
 
-cdef class _SymbolTableIterator(object):
+cdef class _SymbolTableIterator:
 
   cdef SymbolTableView _table
   cdef unique_ptr[fst.SymbolTableIterator] _siter
@@ -193,7 +207,7 @@ cdef class _SymbolTableIterator(object):
 ctypedef fst.EncodeMapperClass * EncodeMapperClass_ptr
 
 
-cdef class EncodeMapper(object):
+cdef class EncodeMapper:
 
   cdef shared_ptr[fst.EncodeMapperClass] _mapper
 
@@ -230,21 +244,16 @@ ctypedef fst.MutableFstClass * MutableFstClass_ptr
 ctypedef fst.VectorFstClass * VectorFstClass_ptr
 
 
-cdef class Fst(object):
+cdef class Fst:
 
   cdef shared_ptr[fst.FstClass] _fst
 
-  # Google-only...
-  @staticmethod
-  cdef string _server_render_svg(const string &)
-  # ...Google-only.
-
   @staticmethod
   cdef string _local_render_svg(const string &)
 
   cpdef string arc_type(self)
 
-  cpdef ArcIterator arcs(self, int64 state)
+  cpdef _ArcIterator arcs(self, int64 state)
 
   cpdef Fst copy(self)
 
@@ -290,7 +299,7 @@ cdef class Fst(object):
 
   cpdef int64 start(self)
 
-  cpdef StateIterator states(self)
+  cpdef _StateIterator states(self)
 
   cpdef bool verify(self)
 
@@ -333,7 +342,7 @@ cdef class MutableFst(Fst):
 
   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *
 
-  cpdef MutableArcIterator mutable_arcs(self, int64 state)
+  cpdef _MutableArcIterator mutable_arcs(self, int64 state)
 
   cpdef int64 num_states(self)
 
@@ -404,7 +413,7 @@ cpdef Fst _read_Fst_from_string(string state)
 # Iterators.
 
 
-cdef class Arc(object):
+cdef class Arc:
 
   cdef unique_ptr[fst.ArcClass] _arc
 
@@ -414,7 +423,7 @@ cdef class Arc(object):
 cdef Arc _init_Arc(const fst.ArcClass &arc)
 
 
-cdef class ArcIterator(object):
+cdef class _ArcIterator:
 
   cdef shared_ptr[fst.FstClass] _fst
   cdef unique_ptr[fst.ArcIteratorClass] _aiter
@@ -436,7 +445,7 @@ cdef class ArcIterator(object):
   cpdef object value(self)
 
 
-cdef class MutableArcIterator(object):
+cdef class _MutableArcIterator:
 
   cdef shared_ptr[fst.MutableFstClass] _mfst
   cdef unique_ptr[fst.MutableArcIteratorClass] _aiter
@@ -460,7 +469,7 @@ cdef class MutableArcIterator(object):
   cpdef object value(self)
 
 
-cdef class StateIterator(object):
+cdef class _StateIterator:
 
   cdef shared_ptr[fst.FstClass] _fst
   cdef unique_ptr[fst.StateIteratorClass] _siter
@@ -580,7 +589,7 @@ cpdef MutableFst synchronize(Fst ifst)
 # Compiler.
 
 
-cdef class Compiler(object):
+cdef class Compiler:
 
   cdef unique_ptr[stringstream] _sstrm
   cdef string _fst_type
@@ -601,7 +610,7 @@ cdef class Compiler(object):
 
 # FarReader.
 
-cdef class FarReader(object):
+cdef class FarReader:
 
   cdef unique_ptr[fst.FarReaderClass] _reader
 
@@ -626,7 +635,7 @@ cdef class FarReader(object):
 
 # FarWriter.
 
-cdef class FarWriter(object):
+cdef class FarWriter:
 
   cdef unique_ptr[fst.FarWriterClass] _writer
 
index 3e9b958..8f7d298 100644 (file)
@@ -1,4 +1,18 @@
 #cython: c_string_encoding=utf8, c_string_type=unicode, language_level=3, nonecheck=True
+# Copyright 2005-2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
@@ -26,7 +40,7 @@ Python variables here use snake_case and constants are in all caps, minus the
 normal `k` prefix.
 """
 
-# Overview of the file:
+# Outline:
 #
 # * Imports
 # * Custom exceptions
@@ -38,8 +52,9 @@ normal `k` prefix.
 # * EncodeMapper
 # * Fst, MutableFst, and VectorFst
 # * FST properties
-# * Arc, ArcIterator, and MutableArcIterator
-# * StateIterator
+# * Arc
+# * _ArcIterator and _MutableArcIterator
+# * _StateIterator
 # * FST operations
 # * Compiler
 # * FarReader and FarWriter
@@ -89,16 +104,6 @@ import os
 import subprocess
 import sys
 
-# Google-only...
-# This only works, and is only needed, inside of Colab.
-try:
-  from colabtools import frontend
-  from colabtools import stubby
-  from google3.visualization.graphviz_server.proto import graphviz_server_pb2
-except ImportError:
-  pass
-# ...Google-only.
-
 
 ## Custom types.
 
@@ -120,9 +125,6 @@ FarType = """typing.Literal[
   "fst",
   "stlist",
   "sttable",
-  # Google-only...
-  "sstable",
-  # ...Google-only.
   "default"
 ]"""
 ProjectType = """typing.Literal["input", "output"]"""
@@ -1572,20 +1574,6 @@ cdef class Fst:
 
   # IPython notebook magic to produce an SVG of the FST.
 
-  # Google-only...
-  @staticmethod
-  cdef string _server_render_svg(const string &dot):
-    # Creates request.
-    request = graphviz_server_pb2.RenderRequest()
-    request.graph.dot = dot
-    request.return_bytes = True
-    # Makes request and returns SVG rendering.
-    response = stubby.Call("blade:graphviz-server",
-                           "RenderServer.Render",
-                           request)
-    return response.rendered_graph.rendered_bytes
-  # ...Google-only.
-
   @staticmethod
   cdef string _local_render_svg(const string &dot):
     proc = subprocess.Popen(("dot", "-Tsvg"),
@@ -1621,13 +1609,6 @@ cdef class Fst:
              False,
              _sstrm,
              b"<pywrapfst>")
-    # Google-only...
-    try:
-      return Fst._server_render_svg(_sstrm.str())
-    except Exception as e:
-      frontend.DisplayToast("GraphViz server request failed: " + str(e))
-      logging.error("Graphviz server requested failed: %s", e)
-    # ...Google-only.
     try:
       return Fst._local_render_svg(_sstrm.str())
     except Exception as e:
@@ -1656,7 +1637,7 @@ cdef class Fst:
     """
     return self._fst.get().ArcType()
 
-  cpdef ArcIterator arcs(self, int64 state):
+  cpdef _ArcIterator arcs(self, int64 state):
     """
     arcs(self, state)
 
@@ -1666,9 +1647,9 @@ cdef class Fst:
       state: The source state ID.
 
     Returns:
-      An ArcIterator.
+      An _ArcIterator.
     """
-    return ArcIterator(self, state)
+    return _ArcIterator(self, state)
 
   cpdef Fst copy(self):
     """
@@ -1977,16 +1958,16 @@ cdef class Fst:
     """
     return self._fst.get().Start()
 
-  cpdef StateIterator states(self):
+  cpdef _StateIterator states(self):
     """
     states(self)
 
     Returns an iterator over all states in the FST.
 
     Returns:
-      A StateIterator object for the FST.
+      A _StateIterator object for the FST.
     """
-    return StateIterator(self)
+    return _StateIterator(self)
 
   cpdef bool verify(self):
     """
@@ -2360,7 +2341,7 @@ cdef class MutableFst(Fst):
     self._minimize(delta, allow_nondet)
     return self
 
-  cpdef MutableArcIterator mutable_arcs(self, int64 state):
+  cpdef _MutableArcIterator mutable_arcs(self, int64 state):
     """
     mutable_arcs(self, state)
 
@@ -2370,9 +2351,9 @@ cdef class MutableFst(Fst):
       state: The source state ID.
 
     Returns:
-      A MutableArcIterator.
+      A _MutableArcIterator.
     """
-    return MutableArcIterator(self, state)
+    return _MutableArcIterator(self, state)
 
   def mutable_input_symbols(self):
     """
@@ -3087,7 +3068,7 @@ ENCODE_WEIGHTS = fst.kEncodeWeights
 ENCODE_FLAGS = fst.kEncodeFlags
 
 
-## Arc, ArcIterator, and MutableArcIterator.
+## Arc.
 
 
 cdef class Arc:
@@ -3157,16 +3138,19 @@ cdef Arc _init_Arc(const fst.ArcClass &arc):
   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)
 
 
-cdef class ArcIterator:
+## _ArcIterator and _MutableArcIterator.
+
+
+cdef class _ArcIterator:
 
   """
-  ArcIterator(ifst, state)
+  _ArcIterator(ifst, state)
 
   This class is used for iterating over the arcs leaving some state of an FST.
   """
 
   def __repr__(self):
-    return f"<ArcIterator at 0x{id(self):x}>"
+    return f"<_ArcIterator at 0x{id(self):x}>"
 
   def __init__(self, Fst ifst, int64 state):
     if not ifst._fst.get().ValidStateId(state):
@@ -3268,17 +3252,17 @@ cdef class ArcIterator:
     return _init_Arc(self._aiter.get().Value())
 
 
-cdef class MutableArcIterator:
+cdef class _MutableArcIterator:
 
   """
-  MutableArcIterator(ifst, state)
+  _MutableArcIterator(ifst, state)
 
   This class is used for iterating over the arcs leaving some state of an FST,
   also permitting mutation of the current arc.
   """
 
   def __repr__(self):
-    return f"<MutableArcIterator at 0x{id(self):x}>"
+    return f"<_MutableArcIterator at 0x{id(self):x}>"
 
   def __init__(self, MutableFst ifst, int64 state):
     if not ifst._fst.get().ValidStateId(state):
@@ -3293,6 +3277,14 @@ cdef class MutableArcIterator:
       yield self.value()
       self.next()
 
+  # Magic method used to get a Pythonic API out of the C++ API.
+  def __next__(self):
+    if self.done():
+      raise StopIteration
+    result = self.value()
+    self.next()
+    return result
+
   cpdef bool done(self):
     """
     done(self)
@@ -3385,19 +3377,19 @@ cdef class MutableArcIterator:
     return _init_Arc(self._aiter.get().Value())
 
 
-## StateIterator.
+## _StateIterator.
 
 
-cdef class StateIterator:
+cdef class _StateIterator:
 
   """
-  StateIterator(ifst)
+  _StateIterator(ifst)
 
   This class is used for iterating over the states in an FST.
   """
 
   def __repr__(self):
-    return f"<StateIterator at 0x{id(self):x}>"
+    return f"<_StateIterator at 0x{id(self):x}>"
 
   def __init__(self, Fst ifst):
     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -3464,11 +3456,12 @@ cdef Fst _map(Fst ifst,
   if not fst.GetMapType(tostring(map_type), addr(_map_type)):
     raise FstArgError(f"Unknown map type: {map_type!r}")
   cdef fst.WeightClass _weight
-  if _map_type == fst.TIMES_MAPPER:
+  if _map_type == fst.MapType.TIMES_MAPPER:
       _weight = _get_WeightClass_or_one(ifst.weight_type(), weight)
   else:
       _weight = _get_WeightClass_or_zero(ifst.weight_type(), weight)
-  return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))
+  return _init_XFst(
+    fst.Map(deref(ifst._fst), _map_type, delta, power, _weight).release())
 
 
 cpdef Fst arcmap(Fst ifst,
@@ -3573,7 +3566,7 @@ cpdef Fst convert(Fst ifst, fst_type=""):
   """
   cdef string _fst_type = tostring(fst_type)
   cdef unique_ptr[fst.FstClass] _tfst
-  _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
+  _tfst = fst.Convert(deref(ifst._fst), _fst_type)
   # Script-land Convert returns a null pointer to signal failure.
   if _tfst.get() == NULL:
     raise FstOpError(f"Conversion to {fst_type!r} failed")
@@ -4146,7 +4139,7 @@ cdef void _shortestdistance(Fst ifst,
   else:
     _opts.reset(
         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
-                                        fst.ANY_ARC_FILTER,
+                                        fst.ArcFilterType.ANY_ARC_FILTER,
                                         nstate,
                                         delta))
     fst.ShortestDistance(deref(ifst._fst), distance, deref(_opts))
@@ -4392,18 +4385,18 @@ cdef class Compiler:
       FstOpError: Compilation failed.
     """
     cdef unique_ptr[fst.FstClass] _tfst
-    _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
-                                       b"<pywrapfst>",
-                                       self._fst_type,
-                                       self._arc_type,
-                                       self._isymbols,
-                                       self._osymbols,
-                                       self._ssymbols,
-                                       self._acceptor,
-                                       self._keep_isymbols,
-                                       self._keep_osymbols,
-                                       self._keep_state_numbering,
-                                       self._allow_negative_labels))
+    _tfst = fst.CompileFstInternal(deref(self._sstrm),
+                                   b"<pywrapfst>",
+                                   self._fst_type,
+                                   self._arc_type,
+                                   self._isymbols,
+                                   self._osymbols,
+                                   self._ssymbols,
+                                   self._acceptor,
+                                   self._keep_isymbols,
+                                   self._keep_osymbols,
+                                   self._keep_state_numbering,
+                                   self._allow_negative_labels)
     self._sstrm.reset(new stringstream())
     if _tfst.get() == NULL:
       raise FstOpError("Compilation failed")
@@ -4477,11 +4470,11 @@ cdef class FarReader:
     """
     cdef vector[string] _sources = [path_tostring(source) for source in sources]
     cdef unique_ptr[fst.FarReaderClass] _tfar
-    _tfar.reset(fst.FarReaderClass.Open(_sources))
+    _tfar = fst.FarReaderClass.Open(_sources)
     if _tfar.get() == NULL:
       raise FstIOError(f"Read failed: {sources!r}")
     cdef FarReader reader = FarReader.__new__(FarReader)
-    reader._reader.reset(_tfar.release())
+    reader._reader = move(_tfar)
     return reader
 
   cpdef string arc_type(self):
@@ -4638,10 +4631,10 @@ cdef class FarWriter:
       FstIOError: Read failed.
     """
     cdef unique_ptr[fst.FarWriterClass] _tfar
-    _tfar.reset(fst.FarWriterClass.Create(
+    _tfar = fst.FarWriterClass.Create(
         path_tostring(source),
         tostring(arc_type),
-        _get_far_type(tostring(far_type))))
+        _get_far_type(tostring(far_type)))
     if _tfar.get() == NULL:
       raise FstIOError(f"Open failed: {source!r}")
     cdef FarWriter writer = FarWriter.__new__(FarWriter)
index a9c25d5..8d2479f 100644 (file)
@@ -15,7 +15,7 @@ libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 22:0:0
+libfstspecial_la_LDFLAGS = -version-info 23:0:0
 
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
index cc4c099..d94ef9c 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -388,7 +388,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../bin $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 22:0:0
+libfstspecial_la_LDFLAGS = -version-info 23:0:0
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
 rho_fst_la_SOURCES = rho-fst.cc
index 2c00f0e..91e7f5a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 6fa8be9..bfad94e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3d8a907..7a9e567 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index b68ca0c..e1ee85d 100644 (file)
@@ -5,13 +5,14 @@ endif
 
 if HAVE_FAR
 far_include_headers = fst/extensions/far/compile-strings.h \
-fst/extensions/far/create.h fst/extensions/far/equal.h \
-fst/extensions/far/extract.h fst/extensions/far/far.h \
-fst/extensions/far/far-class.h fst/extensions/far/farlib.h \
-fst/extensions/far/farscript.h fst/extensions/far/getters.h \
-fst/extensions/far/info.h fst/extensions/far/isomorphic.h \
-fst/extensions/far/print-strings.h fst/extensions/far/script-impl.h \
-fst/extensions/far/stlist.h fst/extensions/far/sttable.h
+fst/extensions/far/convert.h fst/extensions/far/create.h \
+fst/extensions/far/equal.h fst/extensions/far/extract.h \
+fst/extensions/far/far.h fst/extensions/far/far-class.h \
+fst/extensions/far/farlib.h fst/extensions/far/farscript.h \
+fst/extensions/far/getters.h fst/extensions/far/info.h \
+fst/extensions/far/isomorphic.h fst/extensions/far/print-strings.h \
+fst/extensions/far/script-impl.h fst/extensions/far/stlist.h \
+fst/extensions/far/sttable.h
 endif
 
 if HAVE_LINEAR
@@ -102,7 +103,7 @@ fst/cache.h fst/closure.h fst/compact-fst.h fst/compat.h fst/complement.h \
 fst/compose-filter.h fst/compose.h fst/concat.h fst/config.h fst/connect.h \
 fst/const-fst.h fst/determinize.h fst/dfs-visit.h fst/difference.h \
 fst/disambiguate.h fst/edit-fst.h fst/encode.h fst/epsnormalize.h fst/equal.h \
-fst/equivalent.h fst/expanded-fst.h fst/expander-cache.h \
+fst/equivalent.h fst/error-weight.h fst/expanded-fst.h fst/expander-cache.h \
 fst/expectation-weight.h fst/factor-weight.h fst/filter-state.h fst/flags.h \
 fst/float-weight.h fst/fst-decl.h fst/fst.h fst/fstlib.h \
 fst/generic-register.h fst/heap.h fst/icu.h fst/intersect.h \
index bc9570e..ce21052 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -130,40 +130,42 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/connect.h fst/const-fst.h fst/determinize.h \
        fst/dfs-visit.h fst/difference.h fst/disambiguate.h \
        fst/edit-fst.h fst/encode.h fst/epsnormalize.h fst/equal.h \
-       fst/equivalent.h fst/expanded-fst.h fst/expander-cache.h \
-       fst/expectation-weight.h fst/factor-weight.h \
-       fst/filter-state.h fst/flags.h fst/float-weight.h \
-       fst/fst-decl.h fst/fst.h fst/fstlib.h fst/generic-register.h \
-       fst/heap.h fst/icu.h fst/intersect.h fst/interval-set.h \
-       fst/invert.h fst/isomorphic.h fst/label-reachable.h \
-       fst/lexicographic-weight.h fst/lock.h fst/log.h \
-       fst/lookahead-filter.h fst/lookahead-matcher.h fst/map.h \
-       fst/mapped-file.h fst/matcher-fst.h fst/matcher.h fst/memory.h \
-       fst/minimize.h fst/mutable-fst.h fst/pair-weight.h \
-       fst/partition.h fst/power-weight.h fst/power-weight-mappers.h \
-       fst/product-weight.h fst/project.h fst/properties.h \
-       fst/prune.h fst/push.h fst/queue.h fst/randequivalent.h \
-       fst/randgen.h fst/rational.h fst/register.h fst/relabel.h \
-       fst/replace-util.h fst/replace.h fst/reverse.h fst/reweight.h \
-       fst/rmepsilon.h fst/rmfinalepsilon.h fst/set-weight.h \
-       fst/shortest-distance.h fst/shortest-path.h \
-       fst/signed-log-weight.h fst/sparse-power-weight.h \
-       fst/sparse-tuple-weight.h fst/state-map.h \
-       fst/state-reachable.h fst/state-table.h fst/statesort.h \
-       fst/string-weight.h fst/string.h fst/symbol-table-ops.h \
-       fst/symbol-table.h fst/synchronize.h fst/test-properties.h \
-       fst/topsort.h fst/tuple-weight.h fst/types.h fst/union-find.h \
-       fst/union-weight.h fst/union.h fst/util.h fst/vector-fst.h \
-       fst/verify.h fst/visit.h fst/windows_defs.inc fst/weight.h \
+       fst/equivalent.h fst/error-weight.h fst/expanded-fst.h \
+       fst/expander-cache.h fst/expectation-weight.h \
+       fst/factor-weight.h fst/filter-state.h fst/flags.h \
+       fst/float-weight.h fst/fst-decl.h fst/fst.h fst/fstlib.h \
+       fst/generic-register.h fst/heap.h fst/icu.h fst/intersect.h \
+       fst/interval-set.h fst/invert.h fst/isomorphic.h \
+       fst/label-reachable.h fst/lexicographic-weight.h fst/lock.h \
+       fst/log.h fst/lookahead-filter.h fst/lookahead-matcher.h \
+       fst/map.h fst/mapped-file.h fst/matcher-fst.h fst/matcher.h \
+       fst/memory.h fst/minimize.h fst/mutable-fst.h \
+       fst/pair-weight.h fst/partition.h fst/power-weight.h \
+       fst/power-weight-mappers.h fst/product-weight.h fst/project.h \
+       fst/properties.h fst/prune.h fst/push.h fst/queue.h \
+       fst/randequivalent.h fst/randgen.h fst/rational.h \
+       fst/register.h fst/relabel.h fst/replace-util.h fst/replace.h \
+       fst/reverse.h fst/reweight.h fst/rmepsilon.h \
+       fst/rmfinalepsilon.h fst/set-weight.h fst/shortest-distance.h \
+       fst/shortest-path.h fst/signed-log-weight.h \
+       fst/sparse-power-weight.h fst/sparse-tuple-weight.h \
+       fst/state-map.h fst/state-reachable.h fst/state-table.h \
+       fst/statesort.h fst/string-weight.h fst/string.h \
+       fst/symbol-table-ops.h fst/symbol-table.h fst/synchronize.h \
+       fst/test-properties.h fst/topsort.h fst/tuple-weight.h \
+       fst/types.h fst/union-find.h fst/union-weight.h fst/union.h \
+       fst/util.h fst/vector-fst.h fst/verify.h fst/visit.h \
+       fst/windows_defs.inc fst/weight.h \
        fst/extensions/compress/compress.h \
        fst/extensions/compress/compressscript.h \
        fst/extensions/compress/elias.h \
        fst/extensions/far/compile-strings.h \
-       fst/extensions/far/create.h fst/extensions/far/equal.h \
-       fst/extensions/far/extract.h fst/extensions/far/far.h \
-       fst/extensions/far/far-class.h fst/extensions/far/farlib.h \
-       fst/extensions/far/farscript.h fst/extensions/far/getters.h \
-       fst/extensions/far/info.h fst/extensions/far/isomorphic.h \
+       fst/extensions/far/convert.h fst/extensions/far/create.h \
+       fst/extensions/far/equal.h fst/extensions/far/extract.h \
+       fst/extensions/far/far.h fst/extensions/far/far-class.h \
+       fst/extensions/far/farlib.h fst/extensions/far/farscript.h \
+       fst/extensions/far/getters.h fst/extensions/far/info.h \
+       fst/extensions/far/isomorphic.h \
        fst/extensions/far/print-strings.h \
        fst/extensions/far/script-impl.h fst/extensions/far/stlist.h \
        fst/extensions/far/sttable.h \
@@ -407,13 +409,14 @@ top_srcdir = @top_srcdir@
 @HAVE_COMPRESS_TRUE@fst/extensions/compress/compressscript.h fst/extensions/compress/elias.h
 
 @HAVE_FAR_TRUE@far_include_headers = fst/extensions/far/compile-strings.h \
-@HAVE_FAR_TRUE@fst/extensions/far/create.h fst/extensions/far/equal.h \
-@HAVE_FAR_TRUE@fst/extensions/far/extract.h fst/extensions/far/far.h \
-@HAVE_FAR_TRUE@fst/extensions/far/far-class.h fst/extensions/far/farlib.h \
-@HAVE_FAR_TRUE@fst/extensions/far/farscript.h fst/extensions/far/getters.h \
-@HAVE_FAR_TRUE@fst/extensions/far/info.h fst/extensions/far/isomorphic.h \
-@HAVE_FAR_TRUE@fst/extensions/far/print-strings.h fst/extensions/far/script-impl.h \
-@HAVE_FAR_TRUE@fst/extensions/far/stlist.h fst/extensions/far/sttable.h
+@HAVE_FAR_TRUE@fst/extensions/far/convert.h fst/extensions/far/create.h \
+@HAVE_FAR_TRUE@fst/extensions/far/equal.h fst/extensions/far/extract.h \
+@HAVE_FAR_TRUE@fst/extensions/far/far.h fst/extensions/far/far-class.h \
+@HAVE_FAR_TRUE@fst/extensions/far/farlib.h fst/extensions/far/farscript.h \
+@HAVE_FAR_TRUE@fst/extensions/far/getters.h fst/extensions/far/info.h \
+@HAVE_FAR_TRUE@fst/extensions/far/isomorphic.h fst/extensions/far/print-strings.h \
+@HAVE_FAR_TRUE@fst/extensions/far/script-impl.h fst/extensions/far/stlist.h \
+@HAVE_FAR_TRUE@fst/extensions/far/sttable.h
 
 @HAVE_GRM_TRUE@far_include_headers = fst/extensions/far/compile-strings.h \
 @HAVE_GRM_TRUE@fst/extensions/far/create.h fst/extensions/far/equal.h \
@@ -493,7 +496,7 @@ fst/cache.h fst/closure.h fst/compact-fst.h fst/compat.h fst/complement.h \
 fst/compose-filter.h fst/compose.h fst/concat.h fst/config.h fst/connect.h \
 fst/const-fst.h fst/determinize.h fst/dfs-visit.h fst/difference.h \
 fst/disambiguate.h fst/edit-fst.h fst/encode.h fst/epsnormalize.h fst/equal.h \
-fst/equivalent.h fst/expanded-fst.h fst/expander-cache.h \
+fst/equivalent.h fst/error-weight.h fst/expanded-fst.h fst/expander-cache.h \
 fst/expectation-weight.h fst/factor-weight.h fst/filter-state.h fst/flags.h \
 fst/float-weight.h fst/fst-decl.h fst/fst.h fst/fstlib.h \
 fst/generic-register.h fst/heap.h fst/icu.h fst/intersect.h \
index 8fc6237..2091bc8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -462,7 +476,7 @@ class CacheLogAccumulatorData {
 // WeightConvert specialization to and from log64 weights. It is similar to the
 // FastLogAccumator. However here, the accumulated weights are pre-computed and
 // stored only for the states that are visited. The member function Init(fst)
-// has to be called to setup this accumulator.  Space complexity is O(gc_limit).
+// has to be called to setup this accumulator. Space complexity is O(gc_limit).
 template <class Arc>
 class CacheLogAccumulator {
  public:
@@ -685,7 +699,7 @@ class ReplaceAccumulatorData {
   std::vector<std::unique_ptr<const Fst<Arc>>> fst_array_;
 };
 
-// This class accumulates weights in a ReplaceFst.  The 'Init' method takes as
+// This class accumulates weights in a ReplaceFst. The 'Init' method takes as
 // input the argument used to build the ReplaceFst and the ReplaceFst state
 // table. It uses accumulators of type 'Accumulator' in the underlying FSTs.
 template <class Accumulator,
index f6da8d3..f26eb99 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -158,7 +172,8 @@ class AddOnImpl : public FstImpl<typename FST::Arc> {
       hdr.Read(strm, nopts.source);
       nopts.header = &hdr;
     }
-    std::unique_ptr<AddOnImpl> impl(new AddOnImpl(nopts.header->FstType()));
+    // Using `new` to access private constructor for `AddOnImpl`.
+    auto impl = fst::WrapUnique(new AddOnImpl(nopts.header->FstType()));
     if (!impl->ReadHeader(strm, nopts, kMinFileVersion, &hdr)) return nullptr;
     impl.reset();
     int32 magic_number = 0;
index e70c41d..e8a1eda 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -176,7 +190,7 @@ class ArcArenaStateStore {
   };
 
   template <class Expander>
-  State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
+  State *FindOrExpand(Expander &expander, StateId state_id) {
     auto it = cache_.insert(std::pair<StateId, State *>(state_id, nullptr));
     if (!it.second) return it.first->second;
     // Needs a new state.
index 3896f7e..a9a150a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -17,6 +31,7 @@
 
 #include <fst/cache.h>
 #include <fst/mutable-fst.h>
+#include <unordered_map>
 
 
 namespace fst {
@@ -85,12 +100,12 @@ enum MapSymbolsAction {
 // whether the mapping mutates its input, writes to a new result FST, or is an
 // on-the-fly FST. Another dimension is how we pass the mapper. We allow passing
 // the mapper by pointer for cases that we need to change the state of the
-// user's mapper.  This is the case with the EncodeMapper, which is reused
+// user's mapper. This is the case with the EncodeMapper, which is reused
 // during decoding. We also include map versions that pass the mapper by value
 // or const reference when this suffices.
 
 // Maps an arc type A using a mapper function object C, passed
-// by pointer.  This version modifies its Fst input.
+// by pointer. This version modifies its Fst input.
 template <class A, class C>
 void ArcMap(MutableFst<A> *fst, C *mapper) {
   using FromArc = A;
@@ -626,10 +641,10 @@ class ArcIterator<ArcMapFst<A, B, C>>
 template <class A, class B, class C>
 inline void ArcMapFst<A, B, C>::InitStateIterator(
     StateIteratorData<B> *data) const {
-  data->base = new StateIterator<ArcMapFst<A, B, C>>(*this);
+  data->base = fst::make_unique<StateIterator<ArcMapFst<A, B, C>>>(*this);
 }
 
-// Constructs and returns an ArcMapFst.  This allows constructing ArcMapFsts
+// Constructs and returns an ArcMapFst. This allows constructing ArcMapFsts
 // without specifying all the types. The template argument is typically
 // not specified, so a call looks like: MakeArcMapFst(fst, Mapper(...)).
 template <class ArcMapper>
@@ -640,7 +655,7 @@ MakeArcMapFst(const Fst<typename ArcMapper::FromArc> &fst,
                    ArcMapper>(fst, mapper);
 }
 
-// Constructs and returns an ArcMapFst.  As above, but using the
+// Constructs and returns an ArcMapFst. As above, but using the
 // ArcMapFst(..., ArcMapper *) constructor.
 template <class ArcMapper>
 ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc, ArcMapper>
index 9d18cfa..f8ff51d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -12,6 +26,7 @@
 #include <utility>
 
 
+#include <fst/error-weight.h>
 #include <fst/expectation-weight.h>
 #include <fst/float-weight.h>
 #include <fst/lexicographic-weight.h>
@@ -63,6 +78,7 @@ using RealArc = ArcTpl<RealWeight>;
 using Real64Arc = ArcTpl<Real64Weight>;
 using SignedLogArc = ArcTpl<SignedLogWeight>;
 using SignedLog64Arc = ArcTpl<SignedLog64Weight>;
+using ErrorArc = ArcTpl<ErrorWeight>;
 using MinMaxArc = ArcTpl<MinMaxWeight>;
 
 // Arc with integer labels and state IDs and string weights.
index 598e543..2388152 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 8733c6d..8558a73 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 59b868e..7c5be23 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -11,7 +25,6 @@
 #include <functional>
 #include <memory>
 #include <type_traits>
-#include <unordered_map>
 #include <unordered_set>
 #include <vector>
 
@@ -19,6 +32,7 @@
 #include <fst/log.h>
 #include <fst/memory.h>
 #include <fst/windows_defs.inc>
+#include <unordered_map>
 #include <unordered_set>
 
 namespace fst {
index 4ddccb5..800cd52 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -915,23 +929,6 @@ class CacheBaseImpl : public FstImpl<typename State::Arc> {
     state->SetFlags(flags, flags);
   }
 
-// Disabled to ensure PushArc not AddArc is used in existing code
-// TODO(sorenj): re-enable for backing store
-#if 0
-  // AddArc adds a single arc to a state and does incremental cache
-  // book-keeping. For efficiency, prefer PushArc and SetArcs below
-  // when possible.
-  void AddArc(StateId s, const Arc &arc) {
-    auto *state = cache_store_->GetMutableState(s);
-    cache_store_->AddArc(state, arc);
-    if (arc.nextstate >= nknown_states_)
-      nknown_states_ = arc.nextstate + 1;
-    SetExpandedState(s);
-    static constexpr auto flags = kCacheArcs | kCacheRecent;
-    state->SetFlags(flags, flags);
-  }
-#endif
-
   // Adds a single arc to a state but delays cache book-keeping. SetArcs must
   // be called when all PushArc and EmplaceArc calls at a state are complete.
   // Do not mix with calls to AddArc.
@@ -1299,7 +1296,7 @@ class ExpanderCacheStore {
       : store_(opts) {}
 
   template <class Expander>
-  State *FindOrExpand(Expander &expander, StateId s) {  // NOLINT
+  State *FindOrExpand(Expander &expander, StateId s) {
     auto *state = store_.GetMutableState(s);
     if (state->Flags()) {
       state->SetFlags(kCacheRecent, kCacheRecent);
index 1b303e8..ee14f5e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -46,7 +60,7 @@ void Closure(MutableFst<Arc> *fst, ClosureType closure_type) {
     const auto nstart = fst->AddState();
     fst->SetStart(nstart);
     fst->SetFinal(nstart);
-    if (start != kNoLabel) fst->AddArc(nstart, Arc(0, 0, start));
+    if (start != kNoStateId) fst->AddArc(nstart, Arc(0, 0, start));
   }
   fst->SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR),
                      kFstProperties);
index 9cb6fd5..53a4a43 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -35,19 +49,19 @@ struct CompactFstOptions : public CacheOptions {
   explicit CompactFstOptions(const CacheOptions &opts) : CacheOptions(opts) {}
 };
 
-// New (Fst) Compactor interface - used by CompactFst.  This interface
+// New (Fst) Compactor interface - used by CompactFst. This interface
 // allows complete flexibility in how the compaction is accomplished.
 //
 // class Compactor {
 //  public:
-//   // Constructor from the Fst to be compacted.  If compactor is present,
-//   // only optional state should be copied from it.  Examples of this
+//   // Constructor from the Fst to be compacted. If compactor is present,
+//   // only optional state should be copied from it. Examples of this
 //   // optional state include compression level or ArcCompactors.
 //   explicit Compactor(const Fst<Arc> &fst,
 //                      shared_ptr<Compactor> compactor = nullptr);
-//   // Copy constructor.  Must make a thread-safe copy suitable for use by
-//   // by Fst::Copy(/*safe=*/true).  Only thread-unsafe data structures
-//   // need to be deeply copied.  Ideally, this constructor is O(1) and any
+//   // Copy constructor. Must make a thread-safe copy suitable for use by
+//   // by Fst::Copy(/*safe=*/true). Only thread-unsafe data structures
+//   // need to be deeply copied. Ideally, this constructor is O(1) and any
 //   // large structures are thread-safe and shared, while small ones may
 //   // need to be copied.
 //   Compactor(const Compactor &compactor);
@@ -65,7 +79,7 @@ struct CompactFstOptions : public CacheOptions {
 //    public:
 //     State();  // Required, corresponds to kNoStateId.
 //     // This constructor may, of course, also take a const Compactor *
-//     // for the first argument.  It is recommended to use const Compactor *
+//     // for the first argument. It is recommended to use const Compactor *
 //     // if possible, but this can be Compactor * if necessary.
 //     State(Compactor *c, StateId s);  // Accessor for StateId 's'.
 //     StateId GetStateId() const;
@@ -137,8 +151,8 @@ struct CompactFstOptions : public CacheOptions {
 //   // Default constructor (optional, see comment below).
 //   ArcCompactor();
 //
-//   // Copy constructor.  Must make a thread-safe copy suitable for use by
-//   // by Fst::Copy(/*safe=*/true).  Only thread-unsafe data structures
+//   // Copy constructor. Must make a thread-safe copy suitable for use by
+//   // by Fst::Copy(/*safe=*/true). Only thread-unsafe data structures
 //   // need to be deeply copied.
 //   ArcCompactor(const ArcCompactor &);
 //
@@ -161,7 +175,7 @@ struct CompactFstOptions : public CacheOptions {
 //   bool Compatible(const Fst<A> &fst) const;
 //
 //   // Returns the properties that are always true for an FST compacted using
-//   // this compactor.  Any Fst with the inverse of these properties should
+//   // this compactor. Any Fst with the inverse of these properties should
 //   // be incompatible.
 //   uint64 Properties() const;
 //
@@ -185,7 +199,7 @@ struct CompactFstOptions : public CacheOptions {
 //   FSTERROR() << "Compactor: No default constructor";
 // }
 
-// Default implementation data for CompactArcCompactor.  Only old-style
+// Default implementation data for CompactArcCompactor. Only old-style
 // ArcCompactors are supported because the CompactArcStore constructors
 // use the old API.
 //
@@ -236,14 +250,14 @@ class CompactArcStore {
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const;
 
   // Returns the starting index in 'compacts_' of the transitions
-  // for state 'i'.  See class-level comment for further details.
+  // for state 'i'. See class-level comment for further details.
   // Requires that the CompactArcStore was constructed with a
-  // variable out-degree compactor.  Requires 0 <= i <= NumStates().
+  // variable out-degree compactor. Requires 0 <= i <= NumStates().
   // By convention, States(NumStates()) == NumCompacts().
   Unsigned States(ssize_t i) const { return states_[i]; }
 
-  // Returns the compacted Element at position i.  See class-level comment
-  // for further details.  Requires 0 <= i < NumCompacts().
+  // Returns the compacted Element at position i. See class-level comment
+  // for further details. Requires 0 <= i < NumCompacts().
   const Element &Compacts(size_t i) const { return compacts_[i]; }
 
   size_t NumStates() const { return nstates_; }
@@ -422,7 +436,7 @@ template <class ArcCompactor>
 CompactArcStore<Element, Unsigned> *CompactArcStore<Element, Unsigned>::Read(
     std::istream &strm, const FstReadOptions &opts, const FstHeader &hdr,
     const ArcCompactor &arc_compactor) {
-  std::unique_ptr<CompactArcStore> data(new CompactArcStore);
+  auto data = fst::make_unique<CompactArcStore>();
   data->start_ = hdr.Start();
   data->nstates_ = hdr.NumStates();
   data->narcs_ = hdr.NumArcs();
@@ -571,7 +585,7 @@ class CompactArcCompactor {
   CompactArcCompactor(const Iterator b, const Iterator e)
       : CompactArcCompactor(b, e, std::make_shared<ArcCompactor>()) {}
 
-  // Copy constructor.  This makes a thread-safe copy, so requires that
+  // Copy constructor. This makes a thread-safe copy, so requires that
   // The ArcCompactor and CompactStore copy constructors make thread-safe
   // copies.
   CompactArcCompactor(const CompactArcCompactor &compactor)
@@ -848,14 +862,16 @@ class CompactFstImpl
   using ImplBase::SetFinal;
   using ImplBase::SetStart;
 
-  CompactFstImpl() : ImplBase(CompactFstOptions()), compactor_() {
+  CompactFstImpl()
+      : ImplBase(CompactFstOptions()),
+        compactor_(std::make_shared<Compactor>()) {
     SetType(Compactor::Type());
     SetProperties(kNullProperties | kStaticProperties);
   }
 
   // Constructs a CompactFstImpl, creating a new Compactor using
   // Compactor(fst, compactor); this uses the compactor arg only for optional
-  // information, such as compression level.  See the Compactor interface
+  // information, such as compression level. See the Compactor interface
   // description.
   CompactFstImpl(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
                  const CompactFstOptions &opts)
@@ -966,7 +982,7 @@ class CompactFstImpl
   }
 
   static CompactFstImpl *Read(std::istream &strm, const FstReadOptions &opts) {
-    std::unique_ptr<CompactFstImpl> impl(new CompactFstImpl);
+    auto impl = fst::make_unique<CompactFstImpl>();
     FstHeader hdr;
     if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) {
       return nullptr;
@@ -1111,18 +1127,18 @@ class CompactFst
 
   // Constructs a CompactFst, creating a new Compactor using
   // Compactor(fst, compactor); this uses the compactor arg only for optional
-  // information, such as compression level.  See the Compactor interface
+  // information, such as compression level. See the Compactor interface
   // description.
   CompactFst(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
              const CompactFstOptions &opts = CompactFstOptions())
       : ImplToExpandedFst<Impl>(
             std::make_shared<Impl>(fst, std::move(compactor), opts)) {}
 
-  // Convenience constructor taking a Compactor rvalue ref.  Avoids
+  // Convenience constructor taking a Compactor rvalue ref. Avoids
   // clutter of make_shared<Compactor> at call site.
   // Constructs a CompactFst, creating a new Compactor using
   // Compactor(fst, compactor); this uses the compactor arg only for optional
-  // information, such as compression level.  See the Compactor interface
+  // information, such as compression level. See the Compactor interface
   // description.
   CompactFst(const Fst<Arc> &fst, Compactor &&compactor,
              const CompactFstOptions &opts = CompactFstOptions())
@@ -1213,7 +1229,7 @@ bool WriteCompactArcFst(
   size_t num_states = -1;
   auto first_pass_arc_compactor = arc_compactor;
   // Note that GetCompactor will only return non-null if the compactor has the
-  // exact type Compactor == CompactArcFst::Compactor.  This is what we want;
+  // exact type Compactor == CompactArcFst::Compactor. This is what we want;
   // other types must do an extra pass to set the arc compactor state.
   if (const Compactor *const compactor =
           internal::GetCompactor<Compactor>(fst)) {
@@ -1604,7 +1620,7 @@ using StdCompactUnweightedAcceptorFst =
     CompactUnweightedAcceptorFst<StdArc, uint32>;
 
 // Convenience function to make a CompactStringFst from a sequence
-// of Arc::Labels.  LabelIterator must be an input iterator.
+// of Arc::Labels. LabelIterator must be an input iterator.
 template <class Arc, class Unsigned = uint32, class LabelIterator>
 inline CompactStringFst<Arc, Unsigned> MakeCompactStringFst(
     const LabelIterator begin, const LabelIterator end) {
index 00512a1..9c18750 100644 (file)
@@ -46,11 +46,17 @@ void FailedNewHandler();
 namespace fst {
 
 // Downcasting.
+
 template <typename To, typename From>
 inline To down_cast(From *f) {
   return static_cast<To>(f);
 }
 
+template <typename To, typename From>
+inline To down_cast(From &f) {
+  return static_cast<To>(f);
+}
+
 // Bitcasting.
 template <class Dest, class Source>
 inline Dest bit_cast(const Source &source) {
@@ -61,6 +67,23 @@ inline Dest bit_cast(const Source &source) {
   return dest;
 }
 
+namespace internal {
+
+template <typename T>
+struct identity {
+  typedef T type;
+};
+
+template <typename T>
+using identity_t = typename identity<T>::type;
+
+}  // namespace internal
+
+template <typename To>
+constexpr To implicit_cast(typename internal::identity_t<To> to) {
+  return to;
+}
+
 // Checksums.
 class CheckSummer {
  public:
index 5065974..cbb375e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -262,13 +276,13 @@ class ArcIterator<ComplementFst<Arc>> : public ArcIteratorBase<Arc> {
 template <class Arc>
 inline void ComplementFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<ComplementFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<ComplementFst<Arc>>>(*this);
 }
 
 template <class Arc>
 inline void ComplementFst<Arc>::InitArcIterator(
     StateId s, ArcIteratorData<Arc> *data) const {
-  data->base = new ArcIterator<ComplementFst<Arc>>(*this, s);
+  data->base = fst::make_unique<ArcIterator<ComplementFst<Arc>>>(*this, s);
 }
 
 // Useful alias when using StdArc.
index 52a9e82..45431e0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 4c68d00..56cc061 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -25,7 +39,7 @@
 namespace fst {
 
 // Delayed composition options templated on the arc type, the matcher,
-// the composition filter, and the composition state table.  By
+// the composition filter, and the composition state table. By
 // default, the matchers, filter, and state table are constructed by
 // composition. If set below, the user can instead pass in these
 // objects; in that case, ComposeFst takes their ownership. This
@@ -704,7 +718,8 @@ class ArcIterator<ComposeFst<Arc, CacheStore>>
 template <class Arc, class CacheStore>
 inline void ComposeFst<Arc, CacheStore>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<ComposeFst<Arc, CacheStore>>(*this);
+  data->base =
+      fst::make_unique<StateIterator<ComposeFst<Arc, CacheStore>>>(*this);
 }
 
 // Specialized matcher for ComposeFst. Supports MATCH_INPUT or MATCH_OUTPUT,
@@ -731,7 +746,7 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
                     MatchType match_type)
       : owned_fst_(fst.Copy()),
         fst_(*owned_fst_),
-        impl_(static_cast<const Impl *>(fst_.GetImpl())),
+        impl_(fst::down_cast<const Impl *>(fst_.GetImpl())),
         s_(kNoStateId),
         match_type_(match_type),
         matcher1_(impl_->matcher1_->Copy()),
@@ -746,7 +761,7 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
   ComposeFstMatcher(const ComposeFst<Arc, CacheStore> *fst,
                     MatchType match_type)
       : fst_(*fst),
-        impl_(static_cast<const Impl *>(fst_.GetImpl())),
+        impl_(fst::down_cast<const Impl *>(fst_.GetImpl())),
         s_(kNoStateId),
         match_type_(match_type),
         matcher1_(impl_->matcher1_->Copy()),
@@ -762,7 +777,7 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
       bool safe = false)
       : owned_fst_(matcher.fst_.Copy(safe)),
         fst_(*owned_fst_),
-        impl_(static_cast<const Impl *>(fst_.GetImpl())),
+        impl_(fst::down_cast<const Impl *>(fst_.GetImpl())),
         s_(kNoStateId),
         match_type_(matcher.match_type_),
         matcher1_(matcher.matcher1_->Copy(safe)),
@@ -951,7 +966,7 @@ struct ComposeOptions {
 // Times(x, z).
 //
 // The output labels of the first transducer or the input labels of
-// the second transducer must be sorted.  The weights need to form a
+// the second transducer must be sorted. The weights need to form a
 // commutative semiring (valid for TropicalWeight and LogWeight).
 //
 // Complexity:
index 71923d3..2fce885 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -87,7 +101,7 @@ void Concat(RationalFst<Arc> *fst1, const Fst<Arc> &fst2) {
   fst1->GetMutableImpl()->AddConcat(fst2, true);
 }
 
-// Computes the concatentation of two FSTs.  This version modifies its
+// Computes the concatentation of two FSTs. This version modifies its
 // MutableFst argument (in second position).
 //
 // Complexity:
index 448ff59..bc208d1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 920c119..5970ecf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -182,7 +196,7 @@ ConstFstImpl<Arc, Unsigned>::ConstFstImpl(const Fst<Arc> &fst) {
 template <class Arc, class Unsigned>
 ConstFstImpl<Arc, Unsigned> *ConstFstImpl<Arc, Unsigned>::Read(
     std::istream &strm, const FstReadOptions &opts) {
-  std::unique_ptr<ConstFstImpl> impl(new ConstFstImpl());
+  auto impl = fst::make_unique<ConstFstImpl>();
   FstHeader hdr;
   if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return nullptr;
   impl->start_ = hdr.Start();
index 610e468..b8f30ee 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -16,6 +30,7 @@
 
 #include <fst/types.h>
 #include <fst/log.h>
+#include <fst/const-fst.h>
 
 #include <fst/arc-map.h>
 #include <fst/bi-table.h>
@@ -928,16 +943,20 @@ class DeterminizeFst : public ImplToFst<internal::DeterminizeFstImplBase<A>> {
           internal::DeterminizeFsaImpl<Arc, CommonDivisor, Filter, StateTable>>(
           fst, nullptr, nullptr, opts);
     } else if (opts.type == DETERMINIZE_DISAMBIGUATE) {
-      auto rv = std::make_shared<internal::DeterminizeFstImpl<
-          Arc, GALLIC_MIN, CommonDivisor, Filter, StateTable>>(fst, opts);
-      if (!(Weight::Properties() & kPath)) {
-        FSTERROR() << "DeterminizeFst: Weight needs to have the "
-                   << "path property to disambiguate output: "
-                   << Weight::Type();
+      if constexpr (IsPath<Weight>::value) {
+        // Calls disambiguating implementation for non-functional transducers.
+        return std::make_shared<internal::DeterminizeFstImpl<
+            Arc, GALLIC_MIN, CommonDivisor, Filter, StateTable>>(fst, opts);
+      } else {
+        FSTERROR() << "DeterminizeFst: Weight needs to have the path "
+                   << "property to disambiguate output: " << Weight::Type();
+        // Return an error Impl.
+        const ConstFst<Arc> empty_fst;
+        auto rv = std::make_shared<internal::DeterminizeFstImpl<
+            Arc, GALLIC, CommonDivisor, Filter, StateTable>>(empty_fst, opts);
         rv->SetProperties(kError, kError);
+        return rv;
       }
-      // Calls disambiguating implementation for non-functional transducers.
-      return rv;
     } else if (opts.type == DETERMINIZE_FUNCTIONAL) {
       // Calls implementation for functional transducers.
       return std::make_shared<internal::DeterminizeFstImpl<
@@ -1005,7 +1024,7 @@ class ArcIterator<DeterminizeFst<Arc>>
 template <class Arc>
 inline void DeterminizeFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<DeterminizeFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<DeterminizeFst<Arc>>>(*this);
 }
 
 // Useful aliases when using StdArc.
index 72f6119..2d2839c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index b7fbe9d..ef0e32e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 8b81b47..11395d8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index dbca19b..607e156 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -210,7 +224,7 @@ class EditFstData {
   // Provides information for the generic mutable arc iterator.
   void InitMutableArcIterator(StateId s, MutableArcIteratorData<Arc> *data,
                               const WrappedFstT *wrapped) {
-    data->base = new MutableArcIterator<MutableFstT>(
+    data->base = fst::make_unique<MutableArcIterator<MutableFstT>>(
         &edits_, GetEditableInternalId(s, wrapped));
   }
 
@@ -378,10 +392,10 @@ class EditFstImpl : public FstImpl<A> {
   // As it happens, the API for the ImplToMutableFst<I,F> class requires that
   // the implementation class--the template parameter "I"--have a constructor
   // taking a const Fst<A> reference. Accordingly, the constructor here must
-  // perform a static_cast to the WrappedFstT type required by EditFst and
+  // perform a fst::down_cast to the WrappedFstT type required by EditFst and
   // therefore EditFstImpl.
   explicit EditFstImpl(const Fst<Arc> &wrapped)
-      : wrapped_(static_cast<WrappedFstT *>(wrapped.Copy())) {
+      : wrapped_(fst::down_cast<WrappedFstT *>(wrapped.Copy())) {
     FstImpl<Arc>::SetType("edit");
     data_ = std::make_shared<EditFstData<Arc, WrappedFstT, MutableFstT>>();
     // have edits_ inherit all properties from wrapped_
@@ -394,7 +408,7 @@ class EditFstImpl : public FstImpl<A> {
   // the Copy() method of the Fst interface.
   EditFstImpl(const EditFstImpl &impl)
       : FstImpl<Arc>(),
-        wrapped_(static_cast<WrappedFstT *>(impl.wrapped_->Copy(true))),
+        wrapped_(fst::down_cast<WrappedFstT *>(impl.wrapped_->Copy(true))),
         data_(impl.data_) {
     SetProperties(impl.Properties());
   }
@@ -607,7 +621,7 @@ EditFstImpl<Arc, WrappedFstT, MutableFstT>::Read(std::istream &strm,
   wrapped_opts.header = nullptr;
   std::unique_ptr<Fst<Arc>> wrapped_fst(Fst<Arc>::Read(strm, wrapped_opts));
   if (!wrapped_fst) return nullptr;
-  impl->wrapped_.reset(static_cast<WrappedFstT *>(wrapped_fst.release()));
+  impl->wrapped_.reset(fst::down_cast<WrappedFstT *>(wrapped_fst.release()));
   impl->data_ = std::shared_ptr<EditFstData<Arc, WrappedFstT, MutableFstT>>(
       EditFstData<Arc, WrappedFstT, MutableFstT>::Read(strm, opts));
   if (!impl->data_) return nullptr;
index e3b7481..e8873ce 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -17,6 +31,7 @@
 #include <fst/log.h>
 #include <fst/arc-map.h>
 #include <fstream>
+#include <fst/properties.h>
 #include <fst/rmfinalepsilon.h>
 #include <unordered_map>
 
@@ -344,6 +359,7 @@ class EncodeMapper {
               (type_ == ENCODE ? kAddSuperFinalProperties
                                : kRmSuperFinalProperties);
     }
+    if (type_ == ENCODE) mask |= kIDeterministic;
     return outprops & mask;
   }
 
index 18105fb..a7d1895 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 98c4ed0..0141beb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index afde241..9903021 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -18,6 +32,7 @@
 #include <fst/push.h>
 #include <fst/union-find.h>
 #include <fst/vector-fst.h>
+#include <unordered_map>
 
 
 namespace fst {
diff --git a/src/include/fst/error-weight.h b/src/include/fst/error-weight.h
new file mode 100644 (file)
index 0000000..e16d3cd
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef FST_ERROR_WEIGHT_H_
+#define FST_ERROR_WEIGHT_H_
+
+#include <ostream>
+#include <string>
+
+#include <fst/util.h>
+
+namespace fst {
+
+// A Weight that can never be instantiated. This is not a semi-ring.
+// It is used for the arc type of empty FAR files.
+struct ErrorWeight {
+  using ReverseWeight = ErrorWeight;
+
+  ErrorWeight() { FSTERROR() << "ErrorWeight::ErrorWeight called"; }
+
+  uint64 Hash() const { return 0; }
+  bool Member() const { return false; }
+  ErrorWeight Quantize(float = 0.0) const { return ErrorWeight(); }
+  ReverseWeight Reverse() const { return ErrorWeight(); }
+  void Write(std::ostream &) const { }
+
+  static constexpr uint64 Properties() { return 0; }
+  static ErrorWeight Zero() { return ErrorWeight(); }
+  static ErrorWeight One() { return ErrorWeight(); }
+  static ErrorWeight NoWeight() { return ErrorWeight(); }
+
+  static const std::string &Type() {
+    static const auto *const type = new std::string("error");
+    return *type;
+  }
+};
+
+inline bool operator==(const ErrorWeight &, const ErrorWeight &) {
+  return false;
+}
+inline bool operator!=(const ErrorWeight &, const ErrorWeight &) {
+  return false;
+}
+
+inline bool ApproxEqual(const ErrorWeight &, const ErrorWeight &, float) {
+  return false;
+}
+inline ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &) {
+  return ErrorWeight();
+}
+inline ErrorWeight Times(const ErrorWeight &, const ErrorWeight &) {
+  return ErrorWeight();
+}
+inline ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &) {
+  return ErrorWeight();
+}
+
+inline std::ostream &operator<<(std::ostream &strm, const ErrorWeight &) {
+  return strm;
+}
+
+}  // namespace fst
+
+#endif  // FST_ERROR_WEIGHT_H_
index 3562e92..8d6c81e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -56,7 +70,7 @@ class ExpandedFst : public Fst<A> {
     }
     auto *fst = reader(strm, ropts);
     if (!fst) return nullptr;
-    return static_cast<ExpandedFst *>(fst);
+    return fst::down_cast<ExpandedFst *>(fst);
   }
 
   // Read an ExpandedFst from a file; return NULL on error.
@@ -154,7 +168,7 @@ class ImplToExpandedFst : public ImplToFst<Impl, FST> {
 template <class Arc>
 typename Arc::StateId CountStates(const Fst<Arc> &fst) {
   if (fst.Properties(kExpanded, false)) {
-    const auto *efst = static_cast<const ExpandedFst<Arc> *>(&fst);
+    const auto *efst = fst::down_cast<const ExpandedFst<Arc> *>(&fst);
     return efst->NumStates();
   } else {
     typename Arc::StateId nstates = 0;
index 434c4b7..c2e39c3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -165,7 +179,7 @@ class HashExpanderCache {
   }
 
   template <class Expander>
-  State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
+  State *FindOrExpand(Expander &expander, StateId state_id) {
     auto it = cache_.insert(std::pair<StateId, State *>(state_id, nullptr));
     if (!it.second) return it.first->second;
     auto *state = new State;
@@ -203,7 +217,7 @@ class VectorExpanderCache {
   }
 
   template <class Expander>
-  State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
+  State *FindOrExpand(Expander &expander, StateId state_id) {
     if (state_id >= vec_.size()) vec_.resize(state_id + 1);
     auto **slot = &vec_[state_id];
     if (*slot == nullptr) {
index b989b3e..ced4e50 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 //    Zero: <Zero, Zero>
 //    Plus: <a1, b1> + <a2, b2> = <(a1 + a2), (b1 + b2)>
 //    Times: <a1, b1> + <a2, b2> = <(a1 * a2), [(a1 * b2) + (a2 * b1)]>
-//    Division: Undefined.
+//    Division (see Divide() for proof):
+//      For a left-semiring:
+//        <a1, b1> / <a2, b2> = <a1 / a2, (b1 - b2 * (a1 / a2)) / a2>
+//      For a right-semiring:
+//        <a1, b1> / <a2, b2> = <a1 / a2, (b1 - (a1 / a2) * b2) / a2>
 //
 // It is commonly used to store a probability, random variable pair so that
 // the shortest distance gives the posterior probability and the associated
@@ -37,7 +55,8 @@ namespace fst {
 // SparsePowerWeight).
 //
 // If W1 is distinct from W2, it is required that there is an external product
-// between W1 and W2 and if both semriring are commutative, or left or right
+// between W1 and W2 (that is, both Times(W1, W2) -> W2 and Times(W2, W1) -> W2
+// must be defined) and if both semirings are commutative, or left or right
 // semirings, then the result must have those properties.
 template <class W1, class W2>
 class ExpectationWeight : public PairWeight<W1, W2> {
@@ -111,15 +130,54 @@ inline ExpectationWeight<W1, W2> Times(const ExpectationWeight<W1, W2> &w1,
       Plus(Times(w1.Value1(), w2.Value2()), Times(w1.Value2(), w2.Value1())));
 }
 
+// Requires
+// * Divide(W1, W1) -> W1
+// * Divide(W2, W1) -> W2
+// * Times(W1, W2) -> W2
+//   (already required by Times(ExpectationWeight, ExpectationWeight).)
+// * Minus(W2, W2) -> W2
+//   (not part of the Weight interface, so Divide will not compile if
+//    Minus is not defined).
 template <class W1, class W2>
 inline ExpectationWeight<W1, W2> Divide(const ExpectationWeight<W1, W2> &w1,
                                         const ExpectationWeight<W1, W2> &w2,
-                                        DivideType typ = DIVIDE_ANY) {
-  FSTERROR() << "ExpectationWeight::Divide: Not implemented";
-  return ExpectationWeight<W1, W2>::NoWeight();
+                                        DivideType typ) {
+  // No special cases are required for !w1.Member(), !w2.Member(), or
+  // w2 == Zero(), since Minus and Divide will already return NoWeight()
+  // in these cases.
+
+  // For a right-semiring, by the definition of Divide, we are looking for
+  // z = x / y such that (x / y) * y = x.
+  // Let <x1, x2> = x, <y1, y2> = y, <z1, z2> = z.
+  // <z1, z2> * <y1, y2> = <x1, x2>.
+  // By the definition of Times:
+  // z1 * y1 = x1 and
+  // z1 * y2 + z2 * y1 = x2.
+  // So z1 = x1 / y1, and
+  // z2 * y2 = x2 - z1 * y2
+  // z2 = (x2 - z1 * y2) / y2.
+  // The left-semiring case is symmetric. The commutative case allows
+  // additional simplification to
+  // z2 = z1 * (x2 / x1 - y2 / y1) if x1 != 0
+  // z2 = x2 / y1 if x1 == 0, but this requires testing against 0
+  // with ApproxEquals. We just use the right-semiring result in
+  // this case.
+  const auto w11 = w1.Value1();
+  const auto w12 = w1.Value2();
+  const auto w21 = w2.Value1();
+  const auto w22 = w2.Value2();
+  const W1 q1 = Divide(w11, w21, typ);
+  if (typ == DIVIDE_LEFT) {
+    const W2 q2 = Divide(Minus(w12, Times(w22, q1)), w21, typ);
+    return ExpectationWeight<W1, W2>(q1, q2);
+  } else {
+    // Right or commutative semiring.
+    const W2 q2 = Divide(Minus(w12, Times(q1, w22)), w21, typ);
+    return ExpectationWeight<W1, W2>(q1, q2);
+  }
 }
 
-// Specialization for enpectation weight.
+// Specialization for expectation weight.
 template <class W1, class W2>
 class Adder<ExpectationWeight<W1, W2>> {
  public:
index bf692ec..d5df6fd 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index c12e690..651a131 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index acf2ac0..e6615ec 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index c54e8a6..881b0c3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -174,7 +188,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
                                               ? 1
                                               : KeySize(in_source.c_str()));
     if (key_size == 0) {
-      FSTERROR() << "FarCompileStrings: " << in_source << " is not seekable.  "
+      FSTERROR() << "FarCompileStrings: " << in_source << " is not seekable. "
                  << "Read from a file instead or set the --generate_keys flag.";
       return;
     }
@@ -203,13 +217,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
       if (!fst) {
         FSTERROR()
             << "FarCompileStrings: Compiling string number " << n << " in file "
-            << in_source << " failed with token_type = "
-            << (token_type == TokenType::BYTE
-                    ? "byte"
-                    : (token_type == TokenType::UTF8
-                           ? "utf8"
-                           : (token_type == TokenType::SYMBOL ? "symbol"
-                                                              : "unknown")))
+            << in_source << " failed with token_type = " << token_type
             << " and entry_type = "
             << (entry_type == FarEntryType::LINE
                     ? "line"
diff --git a/src/include/fst/extensions/far/convert.h b/src/include/fst/extensions/far/convert.h
new file mode 100644 (file)
index 0000000..f57acc2
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef FST_EXTENSIONS_FAR_CONVERT_H_
+#define FST_EXTENSIONS_FAR_CONVERT_H_
+
+#include <memory>
+#include <string>
+
+#include <fst/extensions/far/far.h>
+#include <fst/extensions/far/getters.h>
+#include <fst/register.h>
+
+namespace fst {
+
+template <class Arc>
+void FarConvert(const std::string &in_source, const std::string &out_source,
+                const std::string &fst_type, const FarType &far_type) {
+  std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(in_source));
+  if (!reader) {
+    FSTERROR() << "FarConvert: Cannot open input FAR: " << in_source;
+    return;
+  }
+
+  std::unique_ptr<FarWriter<Arc>> writer(
+      FarWriter<Arc>::Create(out_source, far_type));
+  if (!writer) {
+    FSTERROR() << "FarConvert: Cannot open output FAR as type "
+               << GetFarTypeString(far_type) << " : " << out_source;
+    return;
+  }
+
+  for (; !reader->Done(); reader->Next()) {
+    const std::string key = reader->GetKey();
+    const Fst<Arc> *const fst = reader->GetFst();
+
+    if (fst_type.empty() || fst->Type() == fst_type) {
+      writer->Add(key, *fst);
+    } else {
+      auto converted_fst = fst::WrapUnique(Convert(*fst, fst_type));
+      if (!converted_fst) {
+        FSTERROR() << "FarConvert: Cannot convert FST with key " << key
+                   << " to " << fst_type;
+        return;
+      }
+
+      writer->Add(key, *converted_fst);
+    }
+  }
+
+  if (reader->Error()) {
+    FSTERROR() << "FarConvert: Error reading FAR: " << in_source;
+  }
+  if (writer->Error()) {
+    FSTERROR() << "FarConvert: Error writing FAR: " << out_source;
+  }
+}
+
+}  // namespace fst
+
+#endif  // FST_EXTENSIONS_FAR_CONVERT_H_
index a141132..29f886f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 376b282..65df80b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 605f7f7..a7a236c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 9fd13bf..7204e4f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -40,45 +54,46 @@ template <class Arc>
 class FarReaderClassImpl : public FarReaderImplBase {
  public:
   explicit FarReaderClassImpl(const std::string &source)
-      : impl_(FarReader<Arc>::Open(source)) {}
+      : reader_(FarReader<Arc>::Open(source)) {}
 
   explicit FarReaderClassImpl(const std::vector<std::string> &sources)
-      : impl_(FarReader<Arc>::Open(sources)) {}
+      : reader_(FarReader<Arc>::Open(sources)) {}
 
   const std::string &ArcType() const final { return Arc::Type(); }
 
-  bool Done() const final { return impl_->Done(); }
+  bool Done() const final { return reader_->Done(); }
 
-  bool Error() const final { return impl_->Error(); }
+  bool Error() const final { return reader_->Error(); }
 
-  bool Find(const std::string &key) final { return impl_->Find(key); }
+  bool Find(const std::string &key) final { return reader_->Find(key); }
 
   const FstClass *GetFstClass() const final {
-    fstc_ = fst::make_unique<FstClass>(*impl_->GetFst());
+    fstc_ = fst::make_unique<FstClass>(*reader_->GetFst());
     return fstc_.get();
   }
 
-  const std::string &GetKey() const final { return impl_->GetKey(); }
+  const std::string &GetKey() const final { return reader_->GetKey(); }
 
-  void Next() final { return impl_->Next(); }
+  void Next() final { return reader_->Next(); }
 
-  void Reset() final { impl_->Reset(); }
+  void Reset() final { reader_->Reset(); }
 
-  FarType Type() const final { return impl_->Type(); }
+  FarType Type() const final { return reader_->Type(); }
 
-  const FarReader<Arc> *GetImpl() const { return impl_.get(); }
+  const FarReader<Arc> *GetFarReader() const { return reader_.get(); }
 
-  FarReader<Arc> *GetImpl() { return impl_.get(); }
+  FarReader<Arc> *GetFarReader() { return reader_.get(); }
 
  private:
-  std::unique_ptr<FarReader<Arc>> impl_;
+  std::unique_ptr<FarReader<Arc>> reader_;
   mutable std::unique_ptr<FstClass> fstc_;
 };
 
 class FarReaderClass;
 
 using OpenFarReaderClassArgs =
-    WithReturnValue<FarReaderClass *, const std::vector<std::string> &>;
+    WithReturnValue<std::unique_ptr<FarReaderClass>,
+                    const std::vector<std::string> &>;
 
 // Untemplated user-facing class holding a templated pimpl.
 class FarReaderClass {
@@ -107,16 +122,16 @@ class FarReaderClass {
   const FarReader<Arc> *GetFarReader() const {
     if (Arc::Type() != ArcType()) return nullptr;
     const FarReaderClassImpl<Arc> *typed_impl =
-        static_cast<FarReaderClassImpl<Arc> *>(impl_.get());
-    return typed_impl->GetImpl();
+        fst::down_cast<FarReaderClassImpl<Arc> *>(impl_.get());
+    return typed_impl->GetFarReader();
   }
 
   template <class Arc>
   FarReader<Arc> *GetFarReader() {
     if (Arc::Type() != ArcType()) return nullptr;
     FarReaderClassImpl<Arc> *typed_impl =
-        static_cast<FarReaderClassImpl<Arc> *>(impl_.get());
-    return typed_impl->GetImpl();
+        fst::down_cast<FarReaderClassImpl<Arc> *>(impl_.get());
+    return typed_impl->GetFarReader();
   }
 
   template <class Arc>
@@ -124,13 +139,15 @@ class FarReaderClass {
 
   // Defined in the CC.
 
-  static FarReaderClass *Open(const std::string &source);
+  static std::unique_ptr<FarReaderClass> Open(const std::string &source);
 
-  static FarReaderClass *Open(const std::vector<std::string> &sources);
+  static std::unique_ptr<FarReaderClass> Open(
+      const std::vector<std::string> &sources);
 
  private:
   template <class Arc>
-  explicit FarReaderClass(FarReaderClassImpl<Arc> *impl) : impl_(impl) {}
+  explicit FarReaderClass(std::unique_ptr<FarReaderClassImpl<Arc>> impl)
+      : impl_(std::move(impl)) {}
 
   std::unique_ptr<FarReaderImplBase> impl_;
 };
@@ -140,7 +157,13 @@ class FarReaderClass {
 
 template <class Arc>
 void OpenFarReaderClass(OpenFarReaderClassArgs *args) {
-  args->retval = new FarReaderClass(new FarReaderClassImpl<Arc>(args->args));
+  auto impl = fst::make_unique<FarReaderClassImpl<Arc>>(args->args);
+  if (impl->GetFarReader() == nullptr) {
+    // Underlying reader failed to open, so return failure here, too.
+    args->retval = nullptr;
+  } else {
+    args->retval = fst::WrapUnique(new FarReaderClass(std::move(impl)));
+  }
 }
 
 // FarWriter API.
@@ -163,7 +186,7 @@ class FarWriterClassImpl : public FarWriterImplBase {
  public:
   explicit FarWriterClassImpl(const std::string &source,
                               FarType type = FarType::DEFAULT)
-      : impl_(FarWriter<Arc>::Create(source, type)) {}
+      : writer_(FarWriter<Arc>::Create(source, type)) {}
 
   bool Add(const std::string &key, const FstClass &fst) final {
     if (ArcType() != fst.ArcType()) {
@@ -171,22 +194,22 @@ class FarWriterClassImpl : public FarWriterImplBase {
                  << "FAR with " << ArcType() << " arcs";
       return false;
     }
-    impl_->Add(key, *(fst.GetFst<Arc>()));
+    writer_->Add(key, *(fst.GetFst<Arc>()));
     return true;
   }
 
   const std::string &ArcType() const final { return Arc::Type(); }
 
-  bool Error() const final { return impl_->Error(); }
+  bool Error() const final { return writer_->Error(); }
 
-  FarType Type() const final { return impl_->Type(); }
+  FarType Type() const final { return writer_->Type(); }
 
-  const FarWriter<Arc> *GetImpl() const { return impl_.get(); }
+  const FarWriter<Arc> *GetFarWriter() const { return writer_.get(); }
 
-  FarWriter<Arc> *GetImpl() { return impl_.get(); }
+  FarWriter<Arc> *GetFarWriter() { return writer_.get(); }
 
  private:
-  std::unique_ptr<FarWriter<Arc>> impl_;
+  std::unique_ptr<FarWriter<Arc>> writer_;
 };
 
 class FarWriterClass;
@@ -194,14 +217,15 @@ class FarWriterClass;
 using CreateFarWriterClassInnerArgs = std::pair<const std::string &, FarType>;
 
 using CreateFarWriterClassArgs =
-    WithReturnValue<FarWriterClass *, CreateFarWriterClassInnerArgs>;
+    WithReturnValue<std::unique_ptr<FarWriterClass>,
+                    CreateFarWriterClassInnerArgs>;
 
 // Untemplated user-facing class holding a templated pimpl.
 class FarWriterClass {
  public:
-  static FarWriterClass *Create(const std::string &source,
-                                const std::string &arc_type,
-                                FarType type = FarType::DEFAULT);
+  static std::unique_ptr<FarWriterClass> Create(
+      const std::string &source, const std::string &arc_type,
+      FarType type = FarType::DEFAULT);
 
   bool Add(const std::string &key, const FstClass &fst) {
     return impl_->Add(key, fst);
@@ -219,16 +243,16 @@ class FarWriterClass {
   const FarWriter<Arc> *GetFarWriter() const {
     if (Arc::Type() != ArcType()) return nullptr;
     const FarWriterClassImpl<Arc> *typed_impl =
-        static_cast<FarWriterClassImpl<Arc> *>(impl_.get());
-    return typed_impl->GetImpl();
+        fst::down_cast<FarWriterClassImpl<Arc> *>(impl_.get());
+    return typed_impl->GetFarWriter();
   }
 
   template <class Arc>
   FarWriter<Arc> *GetFarWriter() {
     if (Arc::Type() != ArcType()) return nullptr;
     FarWriterClassImpl<Arc> *typed_impl =
-        static_cast<FarWriterClassImpl<Arc> *>(impl_.get());
-    return typed_impl->GetImpl();
+        fst::down_cast<FarWriterClassImpl<Arc> *>(impl_.get());
+    return typed_impl->GetFarWriter();
   }
 
   template <class Arc>
@@ -236,7 +260,8 @@ class FarWriterClass {
 
  private:
   template <class Arc>
-  explicit FarWriterClass(FarWriterClassImpl<Arc> *impl) : impl_(impl) {}
+  explicit FarWriterClass(std::unique_ptr<FarWriterClassImpl<Arc>> impl)
+      : impl_(std::move(impl)) {}
 
   std::unique_ptr<FarWriterImplBase> impl_;
 };
@@ -245,8 +270,9 @@ class FarWriterClass {
 // static method FarWriterClass::Create instead.
 template <class Arc>
 void CreateFarWriterClass(CreateFarWriterClassArgs *args) {
-  args->retval = new FarWriterClass(new FarWriterClassImpl<Arc>(
-      std::get<0>(args->args), std::get<1>(args->args)));
+  args->retval = fst::WrapUnique(
+      new FarWriterClass(fst::make_unique<FarWriterClassImpl<Arc>>(
+          std::get<0>(args->args), std::get<1>(args->args))));
 }
 
 }  // namespace script
index d409b44..cef7ff6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -12,6 +26,7 @@
 #include <fst/log.h>
 #include <fst/extensions/far/stlist.h>
 #include <fst/extensions/far/sttable.h>
+#include <fst/arc.h>
 #include <fstream>
 #include <fst/fst.h>
 #include <fst/vector-fst.h>
@@ -20,10 +35,16 @@ namespace fst {
 
 enum class FarEntryType { LINE, FILE };
 
+// Checks for FST magic number in an input stream (to be opened given the source
+// name), to indicate to the caller function that the stream content is an FST
+// header.
 inline bool IsFst(const std::string &source) {
   std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
-  return IsFstHeader(strm, source);
+  int32 magic_number = 0;
+  ReadType(strm, &magic_number);
+  bool match = magic_number == kFstMagicNumber;
+  return match;
 }
 
 // FST archive header class
@@ -35,27 +56,28 @@ class FarHeader {
 
   bool Read(const std::string &source) {
     FstHeader fsthdr;
+    arctype_ = "unknown";
     if (source.empty()) {
       // Header reading unsupported on stdin. Assumes STList and StdArc.
       fartype_ = "stlist";
       arctype_ = "standard";
       return true;
     } else if (IsSTTable(source)) {  // Checks if STTable.
-      ReadSTTableHeader(source, &fsthdr);
       fartype_ = "sttable";
-      arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
+      if (!ReadSTTableHeader(source, &fsthdr)) return false;
+      arctype_ = fsthdr.ArcType().empty() ? ErrorArc::Type() : fsthdr.ArcType();
       return true;
     } else if (IsSTList(source)) {  // Checks if STList.
-      ReadSTListHeader(source, &fsthdr);
       fartype_ = "stlist";
-      arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
+      if (!ReadSTListHeader(source, &fsthdr)) return false;
+      arctype_ = fsthdr.ArcType().empty() ? ErrorArc::Type() : fsthdr.ArcType();
       return true;
     } else if (IsFst(source)) {  // Checks if FST.
+      fartype_ = "fst";
       std::ifstream istrm(source,
                                std::ios_base::in | std::ios_base::binary);
-      fsthdr.Read(istrm, source);
-      fartype_ = "fst";
-      arctype_ = fsthdr.ArcType().empty() ? "unknown" : fsthdr.ArcType();
+      if (!fsthdr.Read(istrm, source)) return false;
+      arctype_ = fsthdr.ArcType().empty() ? ErrorArc::Type() : fsthdr.ArcType();
       return true;
     }
     return false;
@@ -114,7 +136,7 @@ class FarReader {
   // Resets current position to beginning of archive.
   virtual void Reset() = 0;
 
-  // Sets current position to first entry >= key.  Returns true if a match.
+  // Sets current position to first entry >= key. Returns true if a match.
   virtual bool Find(const std::string &key) = 0;
 
   // Current position at end of archive?
@@ -266,15 +288,17 @@ class STTableFarReader : public FarReader<A> {
   using Arc = A;
 
   static STTableFarReader *Open(const std::string &source) {
-    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(source);
+    auto reader =
+        fst::WrapUnique(STTableReader<Fst<Arc>, FstReader<Arc>>::Open(source));
     if (!reader || reader->Error()) return nullptr;
-    return new STTableFarReader(reader);
+    return new STTableFarReader(std::move(reader));
   }
 
   static STTableFarReader *Open(const std::vector<std::string> &sources) {
-    auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(sources);
+    auto reader = fst::WrapUnique(
+        STTableReader<Fst<Arc>, FstReader<Arc>>::Open(sources));
     if (!reader || reader->Error()) return nullptr;
-    return new STTableFarReader(reader);
+    return new STTableFarReader(std::move(reader));
   }
 
   void Reset() final { reader_->Reset(); }
@@ -294,8 +318,9 @@ class STTableFarReader : public FarReader<A> {
   bool Error() const final { return reader_->Error(); }
 
  private:
-  explicit STTableFarReader(STTableReader<Fst<Arc>, FstReader<Arc>> *reader)
-      : reader_(reader) {}
+  explicit STTableFarReader(
+      std::unique_ptr<STTableReader<Fst<Arc>, FstReader<Arc>>> reader)
+      : reader_(std::move(reader)) {}
 
   std::unique_ptr<STTableReader<Fst<Arc>, FstReader<Arc>>> reader_;
 };
@@ -306,15 +331,17 @@ class STListFarReader : public FarReader<A> {
   using Arc = A;
 
   static STListFarReader *Open(const std::string &source) {
-    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(source);
+    auto reader =
+        fst::WrapUnique(STListReader<Fst<Arc>, FstReader<Arc>>::Open(source));
     if (!reader || reader->Error()) return nullptr;
-    return new STListFarReader(reader);
+    return new STListFarReader(std::move(reader));
   }
 
   static STListFarReader *Open(const std::vector<std::string> &sources) {
-    auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(sources);
+    auto reader =
+        fst::WrapUnique(STListReader<Fst<Arc>, FstReader<Arc>>::Open(sources));
     if (!reader || reader->Error()) return nullptr;
-    return new STListFarReader(reader);
+    return new STListFarReader(std::move(reader));
   }
 
   void Reset() final { reader_->Reset(); }
@@ -334,8 +361,9 @@ class STListFarReader : public FarReader<A> {
   bool Error() const final { return reader_->Error(); }
 
  private:
-  explicit STListFarReader(STListReader<Fst<Arc>, FstReader<Arc>> *reader)
-      : reader_(reader) {}
+  explicit STListFarReader(
+      std::unique_ptr<STListReader<Fst<Arc>, FstReader<Arc>>> reader)
+      : reader_(std::move(reader)) {}
 
   std::unique_ptr<STListReader<Fst<Arc>, FstReader<Arc>>> reader_;
 };
index c9bb171..0c5a081 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index fb7124f..116f044 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -12,6 +26,7 @@
 
 #include <fst/types.h>
 #include <fst/extensions/far/compile-strings.h>
+#include <fst/extensions/far/convert.h>
 #include <fst/extensions/far/create.h>
 #include <fst/extensions/far/equal.h>
 #include <fst/extensions/far/extract.h>
@@ -44,30 +59,6 @@ struct FarCompileStringsArgs {
   const bool allow_negative_labels;
   const std::string &key_prefix;
   const std::string &key_suffix;
-
-  FarCompileStringsArgs(const std::vector<std::string> &in_sources,
-                        const std::string &out_source,
-                        const std::string &fst_type, const FarType &far_type,
-                        int32 generate_keys, FarEntryType fet, TokenType tt,
-                        const std::string &symbols_source,
-                        const std::string &unknown_symbol, bool keep_symbols,
-                        bool initial_symbols, bool allow_negative_labels,
-                        const std::string &key_prefix,
-                        const std::string &key_suffix)
-      : in_sources(in_sources),
-        out_source(out_source),
-        fst_type(fst_type),
-        far_type(far_type),
-        generate_keys(generate_keys),
-        fet(fet),
-        tt(tt),
-        symbols_source(symbols_source),
-        unknown_symbol(unknown_symbol),
-        keep_symbols(keep_symbols),
-        initial_symbols(initial_symbols),
-        allow_negative_labels(allow_negative_labels),
-        key_prefix(key_prefix),
-        key_suffix(key_suffix) {}
 };
 
 template <class Arc>
@@ -90,6 +81,23 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
                        const std::string &key_prefix,
                        const std::string &key_suffix);
 
+struct FarConvertArgs {
+  const std::string &in_source;
+  const std::string &out_source;
+  const std::string &fst_type;
+  const FarType &far_type;
+};
+
+template <class Arc>
+void FarConvert(FarConvertArgs *args) {
+  FarConvert<Arc>(args->in_source, args->out_source, args->fst_type,
+                  args->far_type);
+}
+
+void FarConvert(const std::string &in_source, const std::string &out_source,
+                const std::string &arc_type, const std::string &fst_type,
+                const FarType &far_type);
+
 // Note: it is safe to pass these strings as references because this struct is
 // only used to pass them deeper in the call graph. Be sure you understand why
 // this is so before using this struct for anything else!
@@ -100,17 +108,6 @@ struct FarCreateArgs {
   const FarType &far_type;
   const std::string &key_prefix;
   const std::string &key_suffix;
-
-  FarCreateArgs(const std::vector<std::string> &in_sources,
-                const std::string &out_source, const int32 generate_keys,
-                const FarType &far_type, const std::string &key_prefix,
-                const std::string &key_suffix)
-      : in_sources(in_sources),
-        out_source(out_source),
-        generate_keys(generate_keys),
-        far_type(far_type),
-        key_prefix(key_prefix),
-        key_suffix(key_suffix) {}
 };
 
 template <class Arc>
@@ -223,27 +220,6 @@ struct FarPrintStringsArgs {
   const int32 generate_sources;
   const std::string &source_prefix;
   const std::string &source_suffix;
-
-  FarPrintStringsArgs(const std::vector<std::string> &isources,
-                      const FarEntryType entry_type, const TokenType token_type,
-                      const std::string &begin_key, const std::string &end_key,
-                      const bool print_key, const bool print_weight,
-                      const std::string &symbols_source,
-                      const bool initial_symbols, const int32 generate_sources,
-                      const std::string &source_prefix,
-                      const std::string &source_suffix)
-      : isources(isources),
-        entry_type(entry_type),
-        token_type(token_type),
-        begin_key(begin_key),
-        end_key(end_key),
-        print_key(print_key),
-        print_weight(print_weight),
-        symbols_source(symbols_source),
-        initial_symbols(initial_symbols),
-        generate_sources(generate_sources),
-        source_prefix(source_prefix),
-        source_suffix(source_suffix) {}
 };
 
 template <class Arc>
index e15a584..c517dac 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index fa1ffaf..f0e5055 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 11373fb..a0cc231 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 95fd133..8b47f70 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index d960e3e..7697604 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index b6af027..ea0c051 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -260,7 +274,16 @@ bool ReadSTListHeader(const std::string &source, Header *header) {
   }
   std::string key;
   ReadType(strm, &key);
-  header->Read(strm, source + ":" + key);
+  if (!strm) {
+    LOG(ERROR) << "ReadSTListHeader: Error reading key: " << source;
+    return false;
+  }
+  // Empty key is written last, so this is an empty STList.
+  if (key.empty()) return true;
+  if (!header->Read(strm, source + ":" + key)) {
+    LOG(ERROR) << "ReadSTListHeader: Error reading FstHeader: " << source;
+    return false;
+  }
   if (!strm) {
     LOG(ERROR) << "ReadSTListHeader: Error reading file: " << source;
     return false;
index 01c45c4..5d5b361 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -339,7 +353,10 @@ bool ReadSTTableHeader(const std::string &source, Header *header) {
   strm.seekg(i);
   std::string key;
   ReadType(strm, &key);
-  header->Read(strm, source + ":" + key);
+  if (!header->Read(strm, source + ":" + key)) {
+    LOG(ERROR) << "ReadSTTableHeader: Error reading FstHeader: " << source;
+    return false;
+  }
   if (strm.fail()) {
     LOG(ERROR) << "ReadSTTableHeader: Error reading file: " << source;
     return false;
index ed0f8cb..dda75c6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index fdfd379..4fc6411 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -106,16 +120,16 @@ class LinearFstData {
             typename std::vector<Label>::const_iterator>
   PossibleOutputLabels(Label word) const;
 
-  static LinearFstData<A> *Read(std::istream &strm);  // NOLINT
-  std::ostream &Write(std::ostream &strm) const;      // NOLINT
+  static LinearFstData<A> *Read(std::istream &strm);
+  std::ostream &Write(std::ostream &strm) const;
 
  private:
   // Offsets in `output_pool_`
   struct InputAttribute {
     size_t output_begin, output_length;
 
-    std::istream &Read(std::istream &strm);         // NOLINT
-    std::ostream &Write(std::ostream &strm) const;  // NOLINT
+    std::istream &Read(std::istream &strm);
+    std::ostream &Write(std::ostream &strm) const;
   };
 
   // Mapping from input label to per-group feature label
@@ -198,7 +212,7 @@ LinearFstData<A>::PossibleOutputLabels(Label word) const {
 }
 
 template <class A>
-inline LinearFstData<A> *LinearFstData<A>::Read(std::istream &strm) {  // NOLINT
+inline LinearFstData<A> *LinearFstData<A>::Read(std::istream &strm) {
   std::unique_ptr<LinearFstData<A>> data(new LinearFstData<A>());
   ReadType(strm, &(data->max_future_size_));
   ReadType(strm, &(data->max_input_label_));
@@ -221,8 +235,7 @@ inline LinearFstData<A> *LinearFstData<A>::Read(std::istream &strm) {  // NOLINT
 }
 
 template <class A>
-inline std::ostream &LinearFstData<A>::Write(
-    std::ostream &strm) const {  // NOLINT
+inline std::ostream &LinearFstData<A>::Write(std::ostream &strm) const {
   WriteType(strm, max_future_size_);
   WriteType(strm, max_input_label_);
   // Feature groups
@@ -250,7 +263,7 @@ typename A::Label LinearFstData<A>::FindFeature(size_t group,
 
 template <class A>
 inline std::istream &LinearFstData<A>::InputAttribute::Read(
-    std::istream &strm) {  // NOLINT
+    std::istream &strm) {
   ReadType(strm, &output_begin);
   ReadType(strm, &output_length);
   return strm;
@@ -258,7 +271,7 @@ inline std::istream &LinearFstData<A>::InputAttribute::Read(
 
 template <class A>
 inline std::ostream &LinearFstData<A>::InputAttribute::Write(
-    std::ostream &strm) const {  // NOLINT
+    std::ostream &strm) const {
   WriteType(strm, output_begin);
   WriteType(strm, output_length);
   return strm;
@@ -301,7 +314,7 @@ class FeatureGroup {
     return trie_[trie_state].final_weight;
   }
 
-  static FeatureGroup<A> *Read(std::istream &strm) {  // NOLINT
+  static FeatureGroup<A> *Read(std::istream &strm) {
     size_t delay;
     ReadType(strm, &delay);
     int start;
@@ -318,7 +331,7 @@ class FeatureGroup {
     }
   }
 
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::ostream &Write(std::ostream &strm) const {
     WriteType(strm, delay_);
     WriteType(strm, start_);
     WriteType(strm, trie_);
@@ -348,14 +361,14 @@ class FeatureGroup {
           weight(Weight::One()),
           final_weight(Weight::One()) {}
 
-    std::istream &Read(std::istream &strm) {  // NOLINT
+    std::istream &Read(std::istream &strm) {
       ReadType(strm, &back_link);
       ReadType(strm, &weight);
       ReadType(strm, &final_weight);
       return strm;
     }
 
-    std::ostream &Write(std::ostream &strm) const {  // NOLINT
+    std::ostream &Write(std::ostream &strm) const {
       WriteType(strm, back_link);
       WriteType(strm, weight);
       WriteType(strm, final_weight);
@@ -398,13 +411,13 @@ struct FeatureGroup<A>::InputOutputLabel {
     return input == that.input && output == that.output;
   }
 
-  std::istream &Read(std::istream &strm) {  // NOLINT
+  std::istream &Read(std::istream &strm) {
     ReadType(strm, &input);
     ReadType(strm, &output);
     return strm;
   }
 
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::ostream &Write(std::ostream &strm) const {
     WriteType(strm, input);
     WriteType(strm, output);
     return strm;
@@ -497,13 +510,13 @@ class LinearFstData<A>::GroupFeatureMap {
     return true;
   }
 
-  std::istream &Read(std::istream &strm) {  // NOLINT
+  std::istream &Read(std::istream &strm) {
     ReadType(strm, &num_groups_);
     ReadType(strm, &pool_);
     return strm;
   }
 
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::ostream &Write(std::ostream &strm) const {
     WriteType(strm, num_groups_);
     WriteType(strm, pool_);
     return strm;
index 2ba7508..441900b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -141,8 +155,7 @@ class LinearTaggerFstImpl : public CacheImpl<A> {
   static LinearTaggerFstImpl *Read(std::istream &strm,
                                    const FstReadOptions &opts);
 
-  bool Write(std::ostream &strm,  // NOLINT
-             const FstWriteOptions &opts) const {
+  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
     FstHeader header;
     header.SetStart(kNoStateId);
     WriteHeader(strm, opts, kFileVersion, &header);
@@ -428,7 +441,7 @@ void LinearTaggerFstImpl<A>::MatchInput(StateId s, Label ilabel,
 
 template <class A>
 inline LinearTaggerFstImpl<A> *LinearTaggerFstImpl<A>::Read(
-    std::istream &strm, const FstReadOptions &opts) {  // NOLINT
+    std::istream &strm, const FstReadOptions &opts) {
   std::unique_ptr<LinearTaggerFstImpl<A>> impl(new LinearTaggerFstImpl<A>());
   FstHeader header;
   if (!impl->ReadHeader(strm, opts, kMinFileVersion, &header)) {
@@ -508,7 +521,7 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
     }
   }
 
-  static LinearTaggerFst<A> *Read(std::istream &in,  // NOLINT
+  static LinearTaggerFst<A> *Read(std::istream &in,
                                   const FstReadOptions &opts) {
     auto *impl = Impl::Read(in, opts);
     return impl ? new LinearTaggerFst<A>(std::shared_ptr<Impl>(impl)) : nullptr;
@@ -567,7 +580,7 @@ class ArcIterator<LinearTaggerFst<Arc>>
 template <class Arc>
 inline void LinearTaggerFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<LinearTaggerFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<LinearTaggerFst<Arc>>>(*this);
 }
 
 namespace internal {
@@ -709,10 +722,10 @@ class LinearClassifierFstImpl : public CacheImpl<A> {
   //
   // - [internal] is the internal state tuple for `LinearFstData` of
   //   the given class; or kNoTrieNodeId's if in start state.
-  Label &Prediction(std::vector<Label> &state) { return state[0]; }  // NOLINT
+  Label &Prediction(std::vector<Label> &state) { return state[0]; }
   Label Prediction(const std::vector<Label> &state) const { return state[0]; }
 
-  Label &InternalAt(std::vector<Label> &state, int index) {  // NOLINT
+  Label &InternalAt(std::vector<Label> &state, int index) {
     return state[index + 1];
   }
   Label InternalAt(const std::vector<Label> &state, int index) const {
@@ -1026,7 +1039,8 @@ class ArcIterator<LinearClassifierFst<Arc>>
 template <class Arc>
 inline void LinearClassifierFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<LinearClassifierFst<Arc>>(*this);
+  data->base =
+      fst::make_unique<StateIterator<LinearClassifierFst<Arc>>>(*this);
 }
 
 // Specialized Matcher for LinearFsts. This matcher only supports
index 0803ee0..4560328 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -86,7 +100,7 @@ size_t ReplaceCopy(InputIterator first, InputIterator last,
 }
 
 template <class Arc>
-bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
+bool GetVocabRecord(const std::string &vocab, std::istream &strm,
                     SymbolTable *isyms, SymbolTable *fsyms, SymbolTable *osyms,
                     typename Arc::Label *word,
                     std::vector<typename Arc::Label> *feature_labels,
@@ -94,7 +108,7 @@ bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
                     size_t *num_line);
 
 template <class Arc>
-bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
+bool GetModelRecord(const std::string &model, std::istream &strm,
                     SymbolTable *fsyms, SymbolTable *osyms,
                     std::vector<typename Arc::Label> *input_labels,
                     std::vector<typename Arc::Label> *output_labels,
@@ -336,7 +350,7 @@ void LinearCompile(const std::string &arc_type,
                    const std::string &save_osymbols);
 
 template <class Arc>
-bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
+bool GetVocabRecord(const std::string &vocab, std::istream &strm,
                     SymbolTable *isyms, SymbolTable *fsyms, SymbolTable *osyms,
                     typename Arc::Label *word,
                     std::vector<typename Arc::Label> *feature_labels,
@@ -366,7 +380,7 @@ bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
 }
 
 template <class Arc>
-bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
+bool GetModelRecord(const std::string &model, std::istream &strm,
                     SymbolTable *fsyms, SymbolTable *osyms,
                     std::vector<typename Arc::Label> *input_labels,
                     std::vector<typename Arc::Label> *output_labels,
index 2fb6ac0..4bd518c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 1fc4a61..49ee1e1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -34,13 +48,13 @@ struct ParentLabel {
     return parent == that.parent && label == that.label;
   }
 
-  std::istream &Read(std::istream &strm) {  // NOLINT
+  std::istream &Read(std::istream &strm) {
     ReadType(strm, &parent);
     ReadType(strm, &label);
     return strm;
   }
 
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::ostream &Write(std::ostream &strm) const {
     WriteType(strm, parent);
     WriteType(strm, label);
     return strm;
@@ -85,7 +99,7 @@ class NestedTrieTopology {
     }
 
     const_iterator &operator++();
-    const_iterator &operator++(int);  // NOLINT
+    const_iterator &operator++(int);
 
     bool operator==(const const_iterator &that) const {
       return ptr_ == that.ptr_ && cur_node_ == that.cur_node_ &&
@@ -133,8 +147,8 @@ class NestedTrieTopology {
   int Find(int parent, const L &label) const;
   const NextMap &ChildrenOf(int parent) const { return *nodes_[parent]; }
 
-  std::istream &Read(std::istream &strm);         // NOLINT
-  std::ostream &Write(std::ostream &strm) const;  // NOLINT
+  std::istream &Read(std::istream &strm);
+  std::ostream &Write(std::ostream &strm) const;
 
   const_iterator begin() const { return const_iterator(this, 0); }
   const_iterator end() const { return const_iterator(this, NumNodes()); }
@@ -213,8 +227,7 @@ inline int NestedTrieTopology<L, H>::Find(int parent, const L &label) const {
 }
 
 template <class L, class H>
-inline std::istream &NestedTrieTopology<L, H>::Read(
-    std::istream &strm) {  // NOLINT
+inline std::istream &NestedTrieTopology<L, H>::Read(std::istream &strm) {
   NestedTrieTopology new_trie;
   size_t num_nodes;
   if (!ReadType(strm, &num_nodes)) return strm;
@@ -225,8 +238,7 @@ inline std::istream &NestedTrieTopology<L, H>::Read(
 }
 
 template <class L, class H>
-inline std::ostream &NestedTrieTopology<L, H>::Write(
-    std::ostream &strm) const {  // NOLINT
+inline std::ostream &NestedTrieTopology<L, H>::Write(std::ostream &strm) const {
   WriteType(strm, NumNodes());
   for (size_t i = 0; i < NumNodes(); ++i) WriteType(strm, *nodes_[i]);
   return strm;
@@ -287,10 +299,8 @@ class FlatTrieTopology {
   int Insert(int parent, const L &label);
   int Find(int parent, const L &label) const;
 
-  std::istream &Read(std::istream &strm) {  // NOLINT
-    return ReadType(strm, &next_);
-  }
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::istream &Read(std::istream &strm) { return ReadType(strm, &next_); }
+  std::ostream &Write(std::ostream &strm) const {
     return WriteType(strm, next_);
   }
 
@@ -422,12 +432,12 @@ class MutableTrie {
 
   bool operator!=(const MutableTrie &that) const { return !(*this == that); }
 
-  std::istream &Read(std::istream &strm) {  // NOLINT
+  std::istream &Read(std::istream &strm) {
     ReadType(strm, &topology_);
     ReadType(strm, &values_);
     return strm;
   }
-  std::ostream &Write(std::ostream &strm) const {  // NOLINT
+  std::ostream &Write(std::ostream &strm) const {
     WriteType(strm, topology_);
     WriteType(strm, values_);
     return strm;
index 4bb4cb7..1f08448 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -210,8 +224,9 @@ struct MPdtComposeOptions {
   bool connect;                  // Connect output?
   PdtComposeFilter filter_type;  // Which pre-defined filter to use.
 
-  explicit MPdtComposeOptions(bool connect = true,
-                              PdtComposeFilter filter_type = PAREN_FILTER)
+  explicit MPdtComposeOptions(
+      bool connect = true,
+      PdtComposeFilter filter_type = PdtComposeFilter::PAREN)
       : connect(connect), filter_type(filter_type) {}
 };
 
@@ -230,8 +245,8 @@ void Compose(
     const std::vector<typename Arc::Label> &assignments, const Fst<Arc> &ifst2,
     MutableFst<Arc> *ofst,
     const MPdtComposeOptions &opts = MPdtComposeOptions()) {
-  bool expand = opts.filter_type != PAREN_FILTER;
-  bool keep_parens = opts.filter_type != EXPAND_FILTER;
+  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
+  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
   MPdtComposeFstOptions<Arc, true> copts(ifst1, parens, assignments, ifst2,
                                          expand, keep_parens);
   copts.gc_limit = 0;
@@ -253,8 +268,8 @@ void Compose(
         &parens,
     const std::vector<typename Arc::Label> &assignments, MutableFst<Arc> *ofst,
     const MPdtComposeOptions &opts = MPdtComposeOptions()) {
-  bool expand = opts.filter_type != PAREN_FILTER;
-  bool keep_parens = opts.filter_type != EXPAND_FILTER;
+  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
+  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
   MPdtComposeFstOptions<Arc, false> copts(ifst1, ifst2, parens, assignments,
                                           expand, keep_parens);
   copts.gc_limit = 0;
index 341ee7b..29f9516 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -279,7 +293,7 @@ class ArcIterator<MPdtExpandFst<Arc>>
 template <class Arc>
 inline void MPdtExpandFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<MPdtExpandFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<MPdtExpandFst<Arc>>>(*this);
 }
 
 struct MPdtExpandOptions {
index b887c1e..a271843 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 #ifndef FST_EXTENSIONS_MPDT_INFO_H_
 #define FST_EXTENSIONS_MPDT_INFO_H_
 
-#include <unordered_map>
 #include <vector>
 
 #include <fst/types.h>
 #include <fst/extensions/mpdt/mpdt.h>
 #include <fst/fst.h>
+#include <unordered_map>
 #include <unordered_set>
 
 namespace fst {
index 9e4549f..93c60c8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 #ifndef FST_EXTENSIONS_MPDT_MPDT_H_
 #define FST_EXTENSIONS_MPDT_MPDT_H_
 
+#include <algorithm>
 #include <array>
 #include <functional>
 #include <map>
+#include <memory>
 #include <vector>
 
 #include <fst/compat.h>
+#include <fst/types.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <unordered_map>
 
 namespace fst {
 
-enum MPdtType {
-  MPDT_READ_RESTRICT,   // Can only read from first empty stack
-  MPDT_WRITE_RESTRICT,  // Can only write to first empty stack
-  MPDT_NO_RESTRICT,     // No read-write restrictions
+enum class MPdtType : uint8 {
+  READ_RESTRICT,   // Can only read from first empty stack
+  WRITE_RESTRICT,  // Can only write to first empty stack
+  NO_RESTRICT,     // No read-write restrictions
 };
 
 namespace internal {
@@ -39,83 +56,99 @@ namespace internal {
 // were wondering, clearing the map at the end does not help.
 
 template <typename StackId, typename Level, Level nlevels>
-struct StackConfig {
+class StackConfig {
+ public:
   StackConfig() : array_() {}
 
-  StackConfig(const StackConfig<StackId, Level, nlevels> &config) {
-    array_ = config.array_;
-  }
+  StackConfig(const StackConfig &config) { array_ = config.array_; }
 
   StackId &operator[](const int index) { return array_[index]; }
 
   const StackId &operator[](const int index) const { return array_[index]; }
 
-  StackConfig &operator=(const StackConfig<StackId, Level, nlevels> &config) {
+  StackConfig &operator=(const StackConfig &config) {
     if (this == &config) return *this;
     array_ = config.array_;
     return *this;
   }
 
+  friend bool operator<(const StackConfig &config1,
+                        const StackConfig &config2) {
+    return config1.array_ < config2.array_;
+  }
+
+ private:
   std::array<StackId, nlevels> array_;
 };
 
-template <typename StackId, typename Level, Level nlevels>
-class CompConfig {
- public:
-  using Config = StackConfig<StackId, Level, nlevels>;
-
-  bool operator()(const Config &x, const Config &y) const {
-    for (Level level = 0; level < nlevels; ++level) {
-      if (x.array_[level] < y.array_[level]) {
-        return true;
-      } else if (x.array_[level] > y.array_[level]) {
-        return false;
-      }
-    }
-    return false;
-  }
-};
+// Forward declaration so `KeyPair` can declare `KeyPairHasher` its friend.
+template <typename Level>
+class KeyPairHasher;
 
 // Defines the KeyPair type used as the key to MPdtStack.paren_id_map_. The hash
 // function is provided as a separate struct to match templating syntax.
 template <typename Level>
-struct KeyPair {
-  Level level;
-  size_t underlying_id;
-
-  KeyPair(Level level, size_t id) : level(level), underlying_id(id) {}
+class KeyPair {
+ public:
+  KeyPair(Level level, size_t id) : level_(level), underlying_id_(id) {}
 
-  inline bool operator==(const KeyPair<Level> &rhs) const {
-    return level == rhs.level && underlying_id == rhs.underlying_id;
+  inline bool operator==(const KeyPair &rhs) const {
+    return level_ == rhs.level_ && underlying_id_ == rhs.underlying_id_;
   }
+
+ private:
+  friend KeyPairHasher<Level>;
+  Level level_;
+  size_t underlying_id_;
 };
 
 template <typename Level>
 struct KeyPairHasher {
   inline size_t operator()(const KeyPair<Level> &keypair) const {
-    return std::hash<Level>()(keypair.level) ^
-           (std::hash<size_t>()(keypair.underlying_id) << 1);
+    return std::hash<Level>()(keypair.level_) ^
+           (std::hash<size_t>()(keypair.underlying_id_) << 1);
   }
 };
 
 template <typename StackId, typename Level, Level nlevels = 2,
-          MPdtType restrict = MPDT_READ_RESTRICT>
+          MPdtType restrict = MPdtType::READ_RESTRICT>
 class MPdtStack {
  public:
   using Label = Level;
   using Config = StackConfig<StackId, Level, nlevels>;
-  using ConfigToStackId =
-      std::map<Config, StackId, CompConfig<StackId, Level, nlevels>>;
+  using ConfigToStackId = std::map<Config, StackId>;
 
   MPdtStack(const std::vector<std::pair<Label, Label>> &parens,
             const std::vector<Level> &assignments);
 
-  MPdtStack(const MPdtStack &mstack);
+  ~MPdtStack() = default;
+
+  MPdtStack(const MPdtStack &other)
+      : error_(other.error_),
+        min_paren_(other.min_paren_),
+        max_paren_(other.max_paren_),
+        paren_levels_(other.paren_levels_),
+        parens_(other.parens_),
+        paren_map_(other.paren_map_),
+        paren_id_map_(other.paren_id_map_),
+        config_to_stack_id_map_(other.config_to_stack_id_map_),
+        stack_id_to_config_map_(other.stack_id_to_config_map_),
+        next_stack_id_(other.next_stack_id_) {
+    std::transform(other.stacks_.begin(), other.stacks_.end(), stacks_.begin(),
+                   [](const std::unique_ptr<PdtStack<StackId, Label>> &ptr) {
+                     return fst::make_unique<PdtStack<StackId, Label>>(*ptr);
+                   });
+  }
 
-  ~MPdtStack() {
-    for (Level level = 0; level < nlevels; ++level) delete stacks_[level];
+  MPdtStack &operator=(const MPdtStack &other) {
+    *this = MPdtStack(other);
+    return *this;
   }
 
+  MPdtStack(MPdtStack &&) = default;
+
+  MPdtStack &operator=(MPdtStack &&) = default;
+
   StackId Find(StackId stack_id, Label label);
 
   // For now we do not implement Pop since this is needed only for
@@ -198,6 +231,7 @@ class MPdtStack {
     return true;
   }
 
+ private:
   bool error_;
   Label min_paren_;
   Label max_paren_;
@@ -213,7 +247,7 @@ class MPdtStack {
   std::unordered_map<StackId, Config> stack_id_to_config_map_;
   StackId next_stack_id_;
   // Array of stacks.
-  PdtStack<StackId, Label> *stacks_[nlevels];
+  std::array<std::unique_ptr<PdtStack<StackId, Label>>, nlevels> stacks_;
 };
 
 template <typename StackId, typename Level, Level nlevels, MPdtType restrict>
@@ -231,7 +265,7 @@ MPdtStack<StackId, Level, nlevels, restrict>::MPdtStack(
     error_ = true;
     return;
   }
-  std::vector<std::pair<Label, Label>> vectors[nlevels];
+  std::array<std::vector<std::pair<Label, Label>>, nlevels> vectors;
   for (Level i = 0; i < assignments.size(); ++i) {
     // Assignments here start at 0, so assuming the human-readable version has
     // them starting at 1, we should subtract 1 here
@@ -262,7 +296,8 @@ MPdtStack<StackId, Level, nlevels, restrict>::MPdtStack(
   Config neg_one;
   Config zero;
   for (Level level = 0; level < nlevels; ++level) {
-    stacks_[level] = new PdtStack<StackId, Label>(vectors[level]);
+    stacks_[level] =
+        fst::make_unique<PdtStack<StackId, Label>>(vectors[level]);
     neg_one[level] = -1;
     zero[level] = 0;
   }
@@ -273,37 +308,6 @@ MPdtStack<StackId, Level, nlevels, restrict>::MPdtStack(
 }
 
 template <typename StackId, typename Level, Level nlevels, MPdtType restrict>
-MPdtStack<StackId, Level, nlevels, restrict>::MPdtStack(
-    const MPdtStack<StackId, Level, nlevels, restrict> &mstack)
-    : error_(mstack.error_),
-      min_paren_(mstack.min_paren_),
-      max_paren_(mstack.max_paren_),
-      parens_(mstack.parens_),
-      next_stack_id_(mstack.next_stack_id_) {
-  for (const auto &kv : mstack.paren_levels_) {
-    paren_levels_[kv.first] = kv.second;
-  }
-  for (const auto &paren : mstack.parens_) parens_.push_back(paren);
-  for (const auto &kv : mstack.paren_map_) {
-    paren_map_[kv.first] = kv.second;
-  }
-  for (const auto &kv : mstack.paren_id_map_) {
-    paren_id_map_[kv.first] = kv.second;
-  }
-  for (auto it = mstack.config_to_stack_id_map_.begin();
-       it != mstack.config_to_stack_id_map_.end(); ++it) {
-    config_to_stack_id_map_[it->first] = it->second;
-  }
-  for (const auto &kv : mstack.stack_id_to_config_map_) {
-    using Config = StackConfig<StackId, Level, nlevels>;
-    const Config config(kv.second);
-    stack_id_to_config_map_[kv.first] = config;
-  }
-  for (Level level = 0; level < nlevels; ++level)
-    stacks_[level] = mstack.stacks_[level];
-}
-
-template <typename StackId, typename Level, Level nlevels, MPdtType restrict>
 StackId MPdtStack<StackId, Level, nlevels, restrict>::Find(StackId stack_id,
                                                            Level label) {
   // Non-paren.
@@ -320,21 +324,21 @@ StackId MPdtStack<StackId, Level, nlevels, restrict>::Find(StackId stack_id,
   const auto level = paren_levels_.find(label)->second;
   // If the label is an open paren we push:
   //
-  // 1) if the restrict type is not MPDT_WRITE_RESTRICT, or
-  // 2) the restrict type is MPDT_WRITE_RESTRICT, and all the stacks above the
-  // level are empty.
+  // 1) if the restrict type is not MPdtType::WRITE_RESTRICT, or
+  // 2) the restrict type is MPdtType::WRITE_RESTRICT, and all the stacks above
+  // the level are empty.
   if (label == parens_[paren_id].first) {  // Open paren.
-    if (restrict == MPDT_WRITE_RESTRICT) {
+    if (restrict == MPdtType::WRITE_RESTRICT) {
       for (Level upper_level = 0; upper_level < level; ++upper_level) {
         if (!Empty(config, upper_level)) return -1;  // Non-empty stack blocks.
       }
     }
     // If the label is an close paren we pop:
     //
-    // 1) if the restrict type is not MPDT_READ_RESTRICT, or
-    // 2) the restrict type is MPDT_READ_RESTRICT, and all the stacks above the
-    // level are empty.
-  } else if (restrict == MPDT_READ_RESTRICT) {
+    // 1) if the restrict type is not MPdtType::READ_RESTRICT, or
+    // 2) the restrict type is MPdtType::READ_RESTRICT, and all the stacks above
+    // the level are empty.
+  } else if (restrict == MPdtType::READ_RESTRICT) {
     for (Level lower_level = 0; lower_level < level; ++lower_level) {
       if (!Empty(config, lower_level)) return -1;  // Non-empty stack blocks.
     }
index bbf206f..e4b0928 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index f36de7b..efce9e2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 535f592..4904436 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 413dd3f..8fe5bf9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 74f1e7e..c314e71 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 // seeking to the Nth set or clear bit in time O(Log(N)) (or
 // O(log(1/density) if the relevant select index is enabled) where N is the
 // length of the bit vector, and density is the block density of zeros/ones
-// (for Select0/Select1 respectively).  The block density is for block i is
+// (for Select0/Select1 respectively). The block density is for block i is
 // B / span_i, where B is the block size in bits (512); and span_i is
 // Select(B * (i + 1)) - Select(B * i), the range of the bitstring that
-// select index block i indexes.  That is, B 0 (or 1) bits occur over
+// select index block i indexes. That is, B 0 (or 1) bits occur over
 // span_i bits of the bit string.
 //
 // To turn this into the "standard"constant time select, there would need
-// to be a span size threshold.  Block spanning more than this would need
-// to have the position of each bit explicitly recorded.  8k is a typical
+// to be a span size threshold. Block spanning more than this would need
+// to have the position of each bit explicitly recorded. 8k is a typical
 // value for this threshold, but I saw no spans larger than ~6k.
 //
 // In addition, this class allows counting set or clear bits over ranges in
 // constant time.
 //
 // This is accomplished by maintaining an index of the running popcounts
-// of the bitstring.  The index is divided into blocks that cover the
-// size of a cache line (8 64-bit words).  Each entry has one absolute count
+// of the bitstring. The index is divided into blocks that cover the
+// size of a cache line (8 64-bit words). Each entry has one absolute count
 // of all the 1s that appear before the block and 7 relative counts since the
 // beginning of the block.
 //
@@ -53,7 +67,7 @@
 //     Rank1(512 * i + 64 * k) - Rank1(512 * i).
 //
 // This index is queried directly for Rank0 and Rank1 and binary searched
-// for Select0 and Select1.  If configured in the constructor or via
+// for Select0 and Select1. If configured in the constructor or via
 // BuildIndex, additional indices for Select0 and Select1 can be built
 // to reduce these operations to O(log(1/density)) as explained above.
 //
@@ -63,7 +77,7 @@
 // select_0_index_[i] == Select0(512 * i).
 // Similarly for select_1_index_.
 //
-// To save space, the absolute counts are stored as uint32.  Therefore,
+// To save space, the absolute counts are stored as uint32. Therefore,
 // only bitstrings with < 2**32 ones are supported.
 //
 // For each 64 bytes of input (8 8-byte words) there are 12 bytes of index
@@ -147,7 +161,7 @@ class BitmapIndex {
   }
 
   // Return true if any bit between begin inclusive and end exclusive
-  // is set.  0 <= begin <= end <= Bits() is required.
+  // is set. 0 <= begin <= end <= Bits() is required.
   //
   bool TestRange(size_t start, size_t end) const {
     // Rank1 will DCHECK the other requirements.
@@ -193,17 +207,17 @@ class BitmapIndex {
   // If this many or fewer RankIndexEntry blocks need to be searched by
   // FindRankIndexEntry use a linear search instead of a binary search.
   // FindInvertedRankIndexEntry always uses binary search, since linear
-  // search never showed improvements on benchmarks.  The value of 8 was
+  // search never showed improvements on benchmarks. The value of 8 was
   // faster than smaller values on benchmarks, but I do not feel comfortable
   // raising it because there are very few times a higher value would
-  // make a difference.  Thus, whether a higher value helps or hurts is harder
-  // to measure.  TODO(jrosenstock): Try to measure with low bit density.
+  // make a difference. Thus, whether a higher value helps or hurts is harder
+  // to measure. TODO(jrosenstock): Try to measure with low bit density.
   static constexpr uint32 kMaxLinearSearchBlocks = 8;
 
   // A RankIndexEntry covers a block of 8 64-bit words (one cache line on
-  // x86_64 and ARM).  It consists of an absolute count of all the 1s that
+  // x86_64 and ARM). It consists of an absolute count of all the 1s that
   // appear before this block, and 7 relative counts for the 1s within
-  // the block.  relative_ones_count_k = popcount(block[0:k]).
+  // the block. relative_ones_count_k = popcount(block[0:k]).
   // The relative counts are stored in bitfields.
   // A RankIndexEntry takes 12 bytes, for 12/64 = 18.75% overhead.
   // See also documentation at the top of the file.
@@ -314,15 +328,15 @@ class BitmapIndex {
   // Index of positions for Select0
   // select_0_index_[i] == Select0(kBitsPerSelect0Block * i).
   // Empty means there is no index, otherwise, we always add an extra entry
-  // with num_bits_.  Overhead is 4 bytes / 64 bytes of zeros,
-  // so 4/64 times the density of zeros.  This is 6.25% * zeros_density.
+  // with num_bits_. Overhead is 4 bytes / 64 bytes of zeros,
+  // so 4/64 times the density of zeros. This is 6.25% * zeros_density.
   std::vector<uint32> select_0_index_;
 
   // Index of positions for Select1
   // select_1_index_[i] == Select1(kBitsPerSelect1Block * i).
   // Empty means there is no index, otherwise, we always add an extra entry
-  // with num_bits_.  Overhead is 4 bytes / 64 bytes of ones,
-  // so 4/64 times the density of ones.  This is 6.25% * ones_density.
+  // with num_bits_. Overhead is 4 bytes / 64 bytes of ones,
+  // so 4/64 times the density of ones. This is 6.25% * ones_density.
   std::vector<uint32> select_1_index_;
 };
 
index 13a842e..6eab44e 100644 (file)
@@ -1,8 +1,22 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 // NgramFst implements a n-gram language model based upon the LOUDS data
-// structure.  Please refer to "Unary Data Structures for Language Models"
+// structure. Please refer to "Unary Data Structures for Language Models"
 // http://research.google.com/pubs/archive/37218.pdf
 
 #ifndef FST_EXTENSIONS_NGRAM_NGRAM_FST_H_
@@ -96,8 +110,7 @@ class NGramFstImpl : public FstImpl<A> {
     }
   }
 
-  static NGramFstImpl<A> *Read(std::istream &strm,  // NOLINT
-                               const FstReadOptions &opts) {
+  static NGramFstImpl<A> *Read(std::istream &strm, const FstReadOptions &opts) {
     auto impl = fst::make_unique<NGramFstImpl<A>>();
     FstHeader hdr;
     if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return nullptr;
@@ -123,8 +136,7 @@ class NGramFstImpl : public FstImpl<A> {
     return impl.release();
   }
 
-  bool Write(std::ostream &strm,  // NOLINT
-             const FstWriteOptions &opts) const {
+  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
     FstHeader hdr;
     hdr.SetStart(Start());
     hdr.SetNumStates(num_states_);
@@ -276,8 +288,8 @@ class NGramFstImpl : public FstImpl<A> {
   BitmapIndex context_index_;
   // Uses Select0 and Rank1.
   BitmapIndex future_index_;
-  // Uses Get and Rank1.  This wastes space if there are no or few final
-  // states, but it's also small.  TODO(jrosenstock): Look at EliasFanoArray.
+  // Uses Get and Rank1. This wastes space if there are no or few final
+  // states, but it's also small. TODO(jrosenstock): Look at EliasFanoArray.
   BitmapIndex final_index_;
 };
 
@@ -468,7 +480,7 @@ inline void NGramFst<A>::InitArcIterator(StateId s,
                                          ArcIteratorData<A> *data) const {
   GetImpl()->SetInstFuture(s, &inst_);
   GetImpl()->SetInstNode(&inst_);
-  data->base = new ArcIterator<NGramFst<A>>(*this, s);
+  data->base = fst::make_unique<ArcIterator<NGramFst<A>>>(*this, s);
 }
 
 namespace internal {
index a86ea51..7ad479e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -6,6 +20,10 @@
 
 #include <cstdint>
 
+#if defined(__aarch64__)
+#include <arm_neon.h>
+#endif
+
 #include <fst/types.h>
 #include <fst/log.h>
 
 
 namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64. Therefore, v must not be 0.
 inline uint32 nth_bit(uint64 v, uint32 r) {
   DCHECK_NE(v, 0);
   DCHECK_LE(0, r);
   DCHECK_LT(r, __builtin_popcountll(v));
 
   // PDEP example from https://stackoverflow.com/a/27453505
+  // __builtin_ctzll is UB for 0, but the conditions above ensure that can't
+  // happen.
   return __builtin_ctzll(_pdep_u64(uint64{1} << r, v));
 }
 }  // namespace fst
@@ -32,7 +52,7 @@ inline uint32 nth_bit(uint64 v, uint32 r) {
 
 namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64. Therefore, v must not be 0.
 uint32 nth_bit(uint64 v, uint32 r);
 }  // namespace fst
 
@@ -46,14 +66,13 @@ extern const uint8 kSelectInByte[2048];
 }  // namespace internal
 
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64. Therefore, v must not be 0.
 //
 // This version is based on the paper "Broadword Implementation of
 // Rank/Select Queries" by Sebastiano Vigna, p. 5, Algorithm 2, with
 // improvements from "Optimized Succinct Data Structures for Massive Data"
 // by Gog & Petri, 2014.
 inline uint32 nth_bit(const uint64 v, const uint32 r) {
-  constexpr uint64 kOnesStep4 = 0x1111111111111111;
   constexpr uint64 kOnesStep8 = 0x0101010101010101;
   constexpr uint64 kMSBsStep8 = 0x80 * kOnesStep8;
 
@@ -61,10 +80,17 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   DCHECK_LE(0, r);
   DCHECK_LT(r, __builtin_popcountll(v));
 
+#if defined(__aarch64__)
+  // Use the ARM64 CNT instruction to compute a byte-wise popcount.
+  const uint64 s =
+      reinterpret_cast<uint64>(vcnt_s8(reinterpret_cast<uint8x8_t>(v)));
+#else
+  constexpr uint64 kOnesStep4 = 0x1111111111111111;
   uint64 s = v;
   s = s - ((s >> 1) & (0x5 * kOnesStep4));
   s = (s & (0x3 * kOnesStep4)) + ((s >> 2) & (0x3 * kOnesStep4));
   s = (s + (s >> 4)) & (0xF * kOnesStep8);
+#endif
   // s now contains the byte-wise popcounts of v.
 
   // byte_sums contains partial sums of the byte-wise popcounts.
@@ -72,7 +98,7 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   uint64 byte_sums = s * kOnesStep8;
 
   // kPrefixSumOverflow[r] == (0x7F - r) * kOnesStep8, so the high bit is
-  // still set if byte_sums - r > 0, or byte_sums > r.  The first one set
+  // still set if byte_sums - r > 0, or byte_sums > r. The first one set
   // is in the byte with the sum larger than r (since r is 0-based),
   // so this is the byte we need.
   const uint64 b = (byte_sums + internal::kPrefixSumOverflow[r]) & kMSBsStep8;
index ae34aba..32ad62f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index b68bc3f..1fa414b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -8,6 +22,7 @@
 
 #include <list>
 
+#include <fst/types.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/compose.h>
 
@@ -433,18 +448,18 @@ class PdtComposeFstOptions<Arc, false>
   }
 };
 
-enum PdtComposeFilter {
-  PAREN_FILTER,         // Bar-Hillel construction; keeps parentheses.
-  EXPAND_FILTER,        // Bar-Hillel + expansion; removes parentheses.
-  EXPAND_PAREN_FILTER,  // Bar-Hillel + expansion; keeps parentheses.
+enum class PdtComposeFilter : uint8 {
+  PAREN,         // Bar-Hillel construction; keeps parentheses.
+  EXPAND,        // Bar-Hillel + expansion; removes parentheses.
+  EXPAND_PAREN,  // Bar-Hillel + expansion; keeps parentheses.
 };
 
 struct PdtComposeOptions {
   bool connect;                  // Connect output?
   PdtComposeFilter filter_type;  // Pre-defined filter to use.
 
-  explicit PdtComposeOptions(bool connect = true,
-                             PdtComposeFilter filter_type = PAREN_FILTER)
+  explicit PdtComposeOptions(bool connect = true, PdtComposeFilter filter_type =
+                                                      PdtComposeFilter::PAREN)
       : connect(connect), filter_type(filter_type) {}
 };
 
@@ -460,8 +475,8 @@ void Compose(
         &parens,
     const Fst<Arc> &ifst2, MutableFst<Arc> *ofst,
     const PdtComposeOptions &opts = PdtComposeOptions()) {
-  bool expand = opts.filter_type != PAREN_FILTER;
-  bool keep_parens = opts.filter_type != EXPAND_FILTER;
+  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
+  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
   PdtComposeFstOptions<Arc, true> copts(ifst1, parens, ifst2, expand,
                                         keep_parens);
   copts.gc_limit = 0;
@@ -481,8 +496,8 @@ void Compose(
         &parens,
     MutableFst<Arc> *ofst,
     const PdtComposeOptions &opts = PdtComposeOptions()) {
-  bool expand = opts.filter_type != PAREN_FILTER;
-  bool keep_parens = opts.filter_type != EXPAND_FILTER;
+  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
+  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
   PdtComposeFstOptions<Arc, false> copts(ifst1, ifst2, parens, expand,
                                          keep_parens);
   copts.gc_limit = 0;
index 8887155..9ff199e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -283,7 +297,7 @@ class ArcIterator<PdtExpandFst<Arc>>
 template <class Arc>
 inline void PdtExpandFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<PdtExpandFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<PdtExpandFst<Arc>>>(*this);
 }
 
 // PrunedExpand prunes the delayed expansion of a pushdown transducer (PDT)
@@ -296,6 +310,7 @@ inline void PdtExpandFst<Arc>::InitStateIterator(
 // The algorithm works by visiting the delayed ExpandFst using a shortest-stack
 // first queue discipline and relies on the shortest-distance information
 // computed using a reverse shortest-path call to perform the pruning.
+// Requires Arc::Weight is idempotent.
 //
 // The algorithm maintains the same state ordering between the ExpandFst being
 // visited (efst_) and the result of pruning written into the MutableFst (ofst_)
@@ -306,6 +321,7 @@ class PdtPrunedExpand {
   using Label = typename Arc::Label;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
+  static_assert(IsIdempotent<Weight>::value, "Weight must be idempotent.");
 
   using StackId = StateId;
   using Stack = PdtStack<StackId, Label>;
@@ -399,6 +415,7 @@ class PdtPrunedExpand {
     const NaturalLess<Weight> less_;
   };
 
+  // Requires Weight is idempotent.
   class ShortestStackFirstQueue
       : public ShortestFirstQueue<StateId, StackCompare> {
    public:
@@ -773,7 +790,7 @@ bool PdtPrunedExpand<Arc>::ProcOpenParen(StateId s, const Arc &arc, StackId si,
     const auto nd = Times(Distance(s), arc.weight);
     if (less_(nd, Distance(arc.nextstate))) SetDistance(arc.nextstate, nd);
     // FinalDistance not necessary for source state since pruning decided using
-    // meta-arcs above.  But this is a problem with A*, hence the following.
+    // meta-arcs above. But this is a problem with A*, hence the following.
     if (less_(fd, FinalDistance(arc.nextstate)))
       SetFinalDistance(arc.nextstate, fd);
     SetFlags(arc.nextstate, kSourceState, kSourceState);
@@ -902,14 +919,19 @@ void Expand(
     const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
         &parens,
     MutableFst<Arc> *ofst, const PdtExpandOptions<Arc> &opts) {
+  using Weight = typename Arc::Weight;
   PdtExpandFstOptions<Arc> eopts;
   eopts.gc_limit = 0;
   if (opts.weight_threshold == Arc::Weight::Zero()) {
     eopts.keep_parentheses = opts.keep_parentheses;
     *ofst = PdtExpandFst<Arc>(ifst, parens, eopts);
-  } else {
+  } else if constexpr (IsIdempotent<Weight>::value) {
     PdtPrunedExpand<Arc> pruned_expand(ifst, parens, opts.keep_parentheses);
     pruned_expand.Expand(ofst, opts.weight_threshold);
+  } else {
+    FSTERROR() << "Expand: non-Zero weight_threshold with non-idempotent"
+               << " Weight " << Weight::Type();
+    ofst->SetProperties(kError, kError);
   }
   if (opts.connect) Connect(ofst);
 }
index 30bb95b..ce06ad3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 159450e..108a1e2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -6,8 +20,6 @@
 #ifndef FST_EXTENSIONS_PDT_INFO_H_
 #define FST_EXTENSIONS_PDT_INFO_H_
 
-#include <unordered_map>
-#include <unordered_set>
 #include <vector>
 
 #include <fst/types.h>
index c4543de..b32029a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -8,7 +22,6 @@
 
 #include <algorithm>
 #include <set>
-#include <unordered_map>
 #include <vector>
 
 #include <fst/log.h>
@@ -55,28 +68,26 @@ struct ParenState {
   };
 };
 
-// Creates an FST-style const iterator from an STL-style map.
-template <class Map>
-class MapIterator {
+// Creates an FST-style const iterator from range of contiguous values
+// in memory.
+template <class V>
+class SpanIterator {
  public:
-  using StlIterator = typename Map::const_iterator;
-  using ValueType = typename Map::mapped_type;
+  using ValueType = const V;
 
-  MapIterator(const Map &map, StlIterator it)
-      : begin_(it), end_(map.end()), it_(it) {}
-
-  bool Done() const { return it_ == end_ || it_->first != begin_->first; }
-
-  ValueType Value() const { return it_->second; }
+  SpanIterator() = default;
+  explicit SpanIterator(ValueType *begin, ValueType *end)
+      : begin_(begin), end_(end), it_(begin) {}
 
+  bool Done() const { return it_ == end_; }
+  ValueType Value() const { return *it_; }
   void Next() { ++it_; }
-
   void Reset() { it_ = begin_; }
 
  private:
-  const StlIterator begin_;
-  const StlIterator end_;
-  StlIterator it_;
+  ValueType *const begin_ = nullptr;
+  ValueType *const end_ = nullptr;
+  ValueType *it_ = nullptr;
 };
 
 // PdtParenReachable: Provides various parenthesis reachability information.
@@ -91,18 +102,21 @@ class PdtParenReachable {
   using StateHash = typename State::Hash;
 
   // Maps from state ID to reachable paren IDs from (to) that state.
-  using ParenMultimap = std::unordered_multimap<StateId, Label>;
+  using ParenMultimap = std::unordered_map<StateId, std::vector<Label>>;
 
   // Maps from paren ID and state ID to reachable state set ID.
   using StateSetMap = std::unordered_map<State, ssize_t, StateHash>;
 
   // Maps from paren ID and state ID to arcs exiting that state with that
   // Label.
-  using ParenArcMultimap = std::unordered_map<State, Arc, StateHash>;
+  using ParenArcMultimap =
+      std::unordered_map<State, std::vector<Arc>, StateHash>;
 
-  using ParenIterator = MapIterator<ParenMultimap>;
+  using ParenIterator =
+      SpanIterator<typename ParenMultimap::mapped_type::value_type>;
 
-  using ParenArcIterator = MapIterator<ParenArcMultimap>;
+  using ParenArcIterator =
+      SpanIterator<typename ParenArcMultimap::mapped_type::value_type>;
 
   using SetIterator = typename Collection<ssize_t, StateId>::SetIterator;
 
@@ -136,7 +150,16 @@ class PdtParenReachable {
   // Given a state ID, returns an iterator over paren IDs for close (open)
   // parens reachable from that state along balanced paths.
   ParenIterator FindParens(StateId s) const {
-    return ParenIterator(paren_multimap_, paren_multimap_.find(s));
+    const auto parens = paren_multimap_.find(s);
+    if (parens != paren_multimap_.end()) {
+      // Cannot dereference iterators if the vector is empty, but that never
+      // happens. ComputeStateSet always adds something to the vector,
+      // and never leaves an empty vector.
+      DCHECK(!parens->second.empty());
+      return ParenIterator(&*parens->second.begin(), &*parens->second.end());
+    } else {
+      return ParenIterator();
+    }
   }
 
   // Given a paren ID and a state ID s, returns an iterator over states that can
@@ -157,8 +180,17 @@ class PdtParenReachable {
   // paren ID.
   ParenArcIterator FindParenArcs(Label paren_id, StateId s) const {
     const State paren_state(paren_id, s);
-    return ParenArcIterator(paren_arc_multimap_,
-                            paren_arc_multimap_.find(paren_state));
+    const auto paren_arcs = paren_arc_multimap_.find(paren_state);
+    if (paren_arcs != paren_arc_multimap_.end()) {
+      // Cannot dereference iterators if the vector is empty, but that never
+      // happens. ComputeStateSet always adds something to the vector,
+      // and never leaves an empty vector.
+      DCHECK(!paren_arcs->second.empty());
+      return ParenArcIterator(&*paren_arcs->second.begin(),
+                              &*paren_arcs->second.end());
+    } else {
+      return ParenArcIterator();
+    }
   }
 
  private:
@@ -215,11 +247,17 @@ bool PdtParenReachable<Arc>::DFSearch(StateId s) {
         if (!DFSearch(arc.nextstate)) return false;
         for (auto set_iter = FindStates(paren_id, arc.nextstate);
              !set_iter.Done(); set_iter.Next()) {
+          // Recursive DFSearch call may modify paren_arc_multimap_ via
+          // ComputeStateSet, so save the paren arcs to avoid issues
+          // with iterator invalidation.
+          std::vector<StateId> cp_nextstates;
           for (auto paren_arc_iter =
                    FindParenArcs(paren_id, set_iter.Element());
                !paren_arc_iter.Done(); paren_arc_iter.Next()) {
-            const auto &cparc = paren_arc_iter.Value();
-            if (!DFSearch(cparc.nextstate)) return false;
+            cp_nextstates.push_back(paren_arc_iter.Value().nextstate);
+          }
+          for (const StateId cp_nextstate : cp_nextstates) {
+            if (!DFSearch(cp_nextstate)) return false;
           }
         }
       }
@@ -256,24 +294,21 @@ void PdtParenReachable<Arc>::ComputeStateSet(StateId s) {
         paren_set.insert(paren_id);
         state_sets[paren_id].insert(s);
         const State paren_state(paren_id, s);
-        paren_arc_multimap_.insert(std::make_pair(paren_state, arc));
+        paren_arc_multimap_[paren_state].push_back(arc);
       }
     } else {  // Non-paren.
       UpdateStateSet(arc.nextstate, &paren_set, &state_sets);
     }
   }
-  std::vector<StateId> state_set;
-  for (auto paren_iter = paren_set.begin(); paren_iter != paren_set.end();
-       ++paren_iter) {
-    state_set.clear();
-    const auto paren_id = *paren_iter;
-    paren_multimap_.insert(std::make_pair(s, paren_id));
-    for (auto state_iter = state_sets[paren_id].begin();
-         state_iter != state_sets[paren_id].end(); ++state_iter) {
-      state_set.push_back(*state_iter);
-    }
+  std::vector<StateId> state_vec;
+  for (const Label paren_id : paren_set) {
+    paren_multimap_[s].push_back(paren_id);
+
+    const std::set<StateId> &state_set = state_sets[paren_id];
+    state_vec.assign(state_set.begin(), state_set.end());
+
     const State paren_state(paren_id, s);
-    set_map_[paren_state] = state_sets_.FindId(state_set);
+    set_map_[paren_state] = state_sets_.FindId(state_vec);
   }
 }
 
index f1ea637..f587ada 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 
 #include <map>
 #include <set>
-#include <unordered_map>
 
 #include <fst/compat.h>
 #include <fst/log.h>
 #include <fst/fst.h>
 #include <fst/state-table.h>
+#include <unordered_map>
 
 namespace fst {
 
index 41d9898..4ad06c0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 86467a4..3639d40 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -127,7 +141,7 @@ void PdtReplace(PdtReplaceArgs *args) {
 void PdtReplace(const std::vector<std::pair<int64, const FstClass *>> &pairs,
                 MutableFstClass *ofst,
                 std::vector<std::pair<int64, int64>> *parens, int64 root,
-                PdtParserType parser_type = PDT_LEFT_PARSER,
+                PdtParserType parser_type = PdtParserType::LEFT,
                 int64 start_paren_labels = kNoLabel,
                 const std::string &left_paren_prefix = "(_",
                 const std::string &right_paren_prefix = "_)");
index a05da1d..b8298a2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 #include <map>
 #include <memory>
 #include <set>
-#include <unordered_map>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
+#include <fst/types.h>
 #include <fst/replace-util.h>
 #include <fst/replace.h>
 #include <fst/symbol-table-ops.h>
@@ -41,24 +56,24 @@ struct ReplaceParenHash {
 //
 // Mohri, M., and Pereira, F. 1998. Dynamic compilation of weighted context-free
 // grammars. In Proc. ACL, pages 891-897.
-enum PdtParserType {
+enum class PdtParserType : uint8 {
   // Top-down construction. Applied to a simple LL(1) grammar (among others),
   // gives a DPDA. If promoted to a DPDT, with outputs being production
   // numbers, gives a leftmost derivation. Left recursive grammars are
   // problematic in use.
-  PDT_LEFT_PARSER,
+  LEFT,
 
-  // Top-down construction. Similar to PDT_LEFT_PARSE except bounded-stack
+  // Top-down construction. Similar to LEFT except bounded-stack
   // (expandable as an FST) result with regular or, more generally, strongly
   // regular grammars. Epsilons may replace some parentheses, which may
   // introduce some non-determinism.
-  PDT_LEFT_SR_PARSER,
+  LEFT_SR,
 
   /* TODO(riley):
   // Bottom-up construction. Applied to a LR(0) grammar, gives a DPDA.
-  // If promoted to a DPDT, with outputs being the production nubmers,
+  // If promoted to a DPDT, with outputs being the production numbers,
   // gives the reverse of a rightmost derivation.
-  PDT_RIGHT_PARSER,
+  RIGHT,
   */
 };
 
@@ -66,7 +81,8 @@ template <class Arc>
 struct PdtReplaceOptions {
   using Label = typename Arc::Label;
 
-  explicit PdtReplaceOptions(Label root, PdtParserType type = PDT_LEFT_PARSER,
+  explicit PdtReplaceOptions(Label root,
+                             PdtParserType type = PdtParserType::LEFT,
                              Label start_paren_labels = kNoLabel,
                              std::string left_paren_prefix = "(_",
                              std::string right_paren_prefix = ")_")
@@ -96,8 +112,8 @@ class PdtParser {
   using LabelStatePair = std::pair<Label, StateId>;
   using StateWeightPair = std::pair<StateId, Weight>;
   using ParenKey = std::pair<size_t, StateId>;
-  using ParenMap =
-      std::unordered_map<ParenKey, size_t, internal::ReplaceParenHash<StateId>>;
+  using ParenMap = std::unordered_map<ParenKey, size_t,
+                                       internal::ReplaceParenHash<StateId>>;
 
   PdtParser(const std::vector<LabelFstPair> &fst_array,
             const PdtReplaceOptions<Arc> &opts)
@@ -780,18 +796,20 @@ void Replace(
     std::vector<std::pair<typename Arc::Label, typename Arc::Label>> *parens,
     const PdtReplaceOptions<Arc> &opts) {
   switch (opts.type) {
-    case PDT_LEFT_PARSER: {
+    case PdtParserType::LEFT: {
       PdtLeftParser<Arc> pr(ifst_array, opts);
       pr.GetParser(ofst, parens);
       return;
     }
-    case PDT_LEFT_SR_PARSER: {
+    case PdtParserType::LEFT_SR: {
       PdtLeftSRParser<Arc> pr(ifst_array, opts);
       pr.GetParser(ofst, parens);
       return;
     }
     default:
-      FSTERROR() << "Replace: Unknown PDT parser type: " << opts.type;
+      FSTERROR() << "Replace: Unknown PDT parser type: "
+                 << static_cast<std::underlying_type<PdtParserType>::type>(
+                        opts.type);
       ofst->DeleteStates();
       ofst->SetProperties(kError, kError);
       parens->clear();
index 900a408..fb4c5e4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 73e8525..c3c7143 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 006d36b..edd0769 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index afb7fca..9464fb0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index b2333da..df10fdf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -20,9 +34,10 @@ namespace internal {
 template <class Label>
 class SigmaFstMatcherData {
  public:
-  explicit SigmaFstMatcherData(Label sigma_label = FLAGS_sigma_fst_sigma_label,
-                               MatcherRewriteMode rewrite_mode =
-                                   RewriteMode(FLAGS_sigma_fst_rewrite_mode))
+  explicit SigmaFstMatcherData(
+      Label sigma_label = FLAGS_sigma_fst_sigma_label,
+      MatcherRewriteMode rewrite_mode =
+          RewriteMode(FLAGS_sigma_fst_rewrite_mode))
       : sigma_label_(sigma_label), rewrite_mode_(rewrite_mode) {}
 
   SigmaFstMatcherData(const SigmaFstMatcherData &data)
index eff6ac1..28fea77 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -18,7 +32,6 @@
 #include <fst/cache.h>
 #include <fst/test-properties.h>
 
-
 namespace fst {
 
 constexpr uint8 kFactorFinalWeights = 0x01;
@@ -509,7 +522,9 @@ class ArcIterator<FactorWeightFst<Arc, FactorIterator>>
 template <class Arc, class FactorIterator>
 inline void FactorWeightFst<Arc, FactorIterator>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<FactorWeightFst<Arc, FactorIterator>>(*this);
+  data->base =
+      fst::make_unique<StateIterator<FactorWeightFst<Arc, FactorIterator>>>(
+          *this);
 }
 
 }  // namespace fst
index 544690c..d647664 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 700fdee..d32ba00 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -97,7 +111,7 @@ constexpr bool operator==(const FloatWeightTpl<T> &w1,
 #if (defined(__i386__) || defined(__x86_64__)) && !defined(__SSE2_MATH__)
 // With i387 instructions, excess precision on a weight in an 80-bit
 // register may cause it to compare unequal to that same weight when
-// stored to memory.  This breaks =='s reflexivity, in turn breaking
+// stored to memory. This breaks =='s reflexivity, in turn breaking
 // NaturalLess.
 #error "Please compile with -msse -mfpmath=sse, or equivalent."
 #endif
@@ -105,7 +119,7 @@ constexpr bool operator==(const FloatWeightTpl<T> &w1,
 }
 
 // These seemingly unnecessary overloads are actually needed to make
-// comparisons like FloatWeightTpl<float> == float compile.  If only the
+// comparisons like FloatWeightTpl<float> == float compile. If only the
 // templated version exists, the FloatWeightTpl<float>(float) conversion
 // won't be found.
 constexpr bool operator==(const FloatWeightTpl<float> &w1,
@@ -451,15 +465,15 @@ using Log64Weight = LogWeightTpl<double>;
 
 namespace internal {
 
-// -log(e^-x + e^-y) = x - LogPosExp(y - x), assuming x >= 0.0.
+// -log(e^-x + e^-y) = x - LogPosExp(y - x), assuming y >= x.
 inline double LogPosExp(double x) {
   DCHECK(!(x < 0));  // NB: NaN values are allowed.
   return log1p(exp(-x));
 }
 
-// -log(e^-x - e^-y) = x - LogNegExp(y - x), assuming x > 0.0.
+// -log(e^-x - e^-y) = x - LogNegExp(y - x), assuming y >= x.
 inline double LogNegExp(double x) {
-  DCHECK_GT(x, 0);
+  DCHECK(!(x < 0));  // NB: NaN values are allowed.
   return log1p(-exp(-x));
 }
 
@@ -516,6 +530,30 @@ inline LogWeightTpl<double> Plus(const LogWeightTpl<double> &w1,
   return Plus<double>(w1, w2);
 }
 
+// Returns NoWeight if w1 < w2 (w1.Value() > w2.Value()).
+template <class T>
+inline LogWeightTpl<T> Minus(const LogWeightTpl<T> &w1,
+                             const LogWeightTpl<T> &w2) {
+  using Limits = FloatLimits<T>;
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f1 > f2) return LogWeightTpl<T>::NoWeight();
+  if (f2 == Limits::PosInfinity()) return f1;
+  const T d = f2 - f1;
+  if (d == Limits::PosInfinity()) return f1;
+  return f1 - internal::LogNegExp(d);
+}
+
+inline LogWeightTpl<float> Minus(const LogWeightTpl<float> &w1,
+                                 const LogWeightTpl<float> &w2) {
+  return Minus<float>(w1, w2);
+}
+
+inline LogWeightTpl<double> Minus(const LogWeightTpl<double> &w1,
+                                  const LogWeightTpl<double> &w2) {
+  return Minus<double>(w1, w2);
+}
+
 template <class T>
 constexpr LogWeightTpl<T> Times(const LogWeightTpl<T> &w1,
                                 const LogWeightTpl<T> &w2) {
index 5ef194b..14f1ab2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 94f28c4..80e3948 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 #include <fst/symbol-table.h>
 #include <fst/util.h>
 
+#ifndef OPENFST_HAVE_STD_STRING_VIEW
+#ifdef __has_include
+#if __has_include(<string_view>) && __cplusplus >= 201703L
+#define OPENFST_HAVE_STD_STRING_VIEW 1
+#endif
+#endif
+#endif
+#ifdef OPENFST_HAVE_STD_STRING_VIEW
+#include <string_view>
+#else
+#include <string>
+#endif
+
+
 
 DECLARE_bool(fst_align);
 
 namespace fst {
 
-bool IsFstHeader(std::istream &, const std::string &);
+// Identifies stream data as an FST (and its endianity).
+constexpr int32 kFstMagicNumber = 2125659606;
 
 class FstHeader;
 
@@ -66,12 +95,12 @@ struct FstReadOptions {
   bool read_isymbols;           // Read isymbols, if any (default: true).
   bool read_osymbols;           // Read osymbols, if any (default: true).
 
-  explicit FstReadOptions(const std::string &source = "<unspecified>",
+  explicit FstReadOptions(const std::string_view source = "<unspecified>",
                           const FstHeader *header = nullptr,
                           const SymbolTable *isymbols = nullptr,
                           const SymbolTable *osymbols = nullptr);
 
-  explicit FstReadOptions(const std::string &source,
+  explicit FstReadOptions(const std::string_view source,
                           const SymbolTable *isymbols,
                           const SymbolTable *osymbols = nullptr);
 
@@ -90,7 +119,7 @@ struct FstWriteOptions {
   bool align;           // Write data aligned (may fail on pipes)?
   bool stream_write;    // Avoid seek operations in writing.
 
-  explicit FstWriteOptions(const std::string &source = "<unspecifed>",
+  explicit FstWriteOptions(std::string_view source = "<unspecified>",
                            bool write_header = true, bool write_isymbols = true,
                            bool write_osymbols = true,
                            bool align = FLAGS_fst_align,
@@ -187,7 +216,7 @@ constexpr int kNoStateId = -1;  // Not a valid state ID.
 
 // A generic FST, templated on the arc definition, with common-demoninator
 // methods (use StateIterator and ArcIterator to iterate over its states and
-// arcs).  Derived classes should be assumed to be thread-unsafe unless
+// arcs). Derived classes should be assumed to be thread-unsafe unless
 // otherwise specified.
 template <class A>
 class Fst {
@@ -362,8 +391,8 @@ template <class Arc>
 struct StateIteratorData {
   using StateId = typename Arc::StateId;
 
-  // Specialized iterator if non-zero.
-  StateIteratorBase<Arc> *base;
+  // Specialized iterator if non-null.
+  std::unique_ptr<StateIteratorBase<Arc>> base;
   // Otherwise, the total number of states.
   StateId nstates;
 
@@ -396,8 +425,6 @@ class StateIterator {
     fst.InitStateIterator(&data_);
   }
 
-  ~StateIterator() { delete data_.base; }
-
   bool Done() const {
     return data_.base ? data_.base->Done() : s_ >= data_.nstates;
   }
@@ -477,10 +504,12 @@ struct ArcIteratorData {
 
   ArcIteratorData &operator=(const ArcIteratorData &) = delete;
 
-  ArcIteratorBase<Arc> *base;  // Specialized iterator if non-zero.
-  const Arc *arcs;             // O.w. arcs pointer
-  size_t narcs;                // ... and arc count.
-  int *ref_count;              // ... and reference count if non-zero.
+  std::unique_ptr<ArcIteratorBase<Arc>>
+      base;         // Specialized iterator if non-null.
+  const Arc *arcs;  // O.w. arcs pointer
+  size_t narcs;     // ... and arc count.
+  int *ref_count;   // ... and a reference count of the `narcs`-length `arcs`
+                    //     array if non-null.
 };
 
 // Generic arc iterator, templated on the FST definition (a wrapper around a
@@ -506,14 +535,10 @@ class ArcIterator {
     fst.InitArcIterator(s, &data_);
   }
 
-  explicit ArcIterator(const ArcIteratorData<Arc> &data) : data_(data), i_(0) {
-    if (data_.ref_count) ++(*data_.ref_count);
-  }
+  explicit ArcIterator(const ArcIteratorData<Arc> &data) = delete;
 
   ~ArcIterator() {
-    if (data_.base) {
-      delete data_.base;
-    } else if (data_.ref_count) {
+    if (data_.ref_count) {
       --(*data_.ref_count);
     }
   }
@@ -651,8 +676,8 @@ inline size_t NumOutputEpsilons(const Fst<Arc> &fst, typename Arc::StateId s) {
 // FST library.
 //
 // This class is thread-compatible except for the const SetProperties
-// overload.  Derived classes should be assumed to be thread-unsafe unless
-// otherwise specified.  Derived-class copy constructors must produce a
+// overload. Derived classes should be assumed to be thread-unsafe unless
+// otherwise specified. Derived-class copy constructors must produce a
 // thread-safe copy.
 template <class Arc>
 class FstImpl {
@@ -726,7 +751,7 @@ class FstImpl {
     // If properties_ and props are compatible (for example kAcceptor and
     // kNoAcceptor cannot both be set), the props can be or-ed in.
     // Compatibility is ensured if props comes from ComputeProperties
-    // and properties_ is set correctly initially.  However
+    // and properties_ is set correctly initially. However
     // relying on properties to be set correctly is too large an
     // assumption, as many places set them incorrectly.
     // Therefore, we or in only the newly discovered properties.
@@ -926,7 +951,7 @@ uint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known);
 // This is a helper class template useful for attaching an FST interface to
 // its implementation, handling reference counting.
 // Thread-unsafe due to Properties (a const function) calling
-// Impl::SetProperties.  TODO(jrosenstock): Make thread-compatible.
+// Impl::SetProperties. TODO(jrosenstock): Make thread-compatible.
 // Impl's copy constructor must produce a thread-safe copy.
 template <class Impl, class FST = Fst<typename Impl::Arc>>
 class ImplToFst : public FST {
@@ -956,7 +981,7 @@ class ImplToFst : public FST {
       uint64 knownprops,
           testprops = internal::TestProperties(*this, mask, &knownprops);
       // Properties is a const member function, but can set the cached
-      // properties.  UpdateProperties does this thread-safely via atomics.
+      // properties. UpdateProperties does this thread-safely via atomics.
       impl_->UpdateProperties(testprops, knownprops);
       return testprops & mask;
     } else {
index e8b1c3a..f2db008 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 9e98098..49e4224 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 40aa7df..73ffb6c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -74,7 +88,7 @@ class Heap {
     return top;
   }
 
-  // Returns the least value w.r.t.  the comparison function from the
+  // Returns the least value w.r.t. the comparison function from the
   // heap.
   const Value &Top() const { return values_.front(); }
 
index ddddda9..e2fe907 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 48a1c59..8d7b196 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 3677c85..b306b0f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e94cd61..105e7c7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 923c006..8b94d9c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -142,8 +156,8 @@ class Isomorphism {
 template <class Arc>
 bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
   if (!ApproxEqual(fst1_->Final(s1), fst2_->Final(s2), delta_)) {
-    VLOG(1) << "Isomorphic: Final weights not equal to within delta="
-            << delta_ << ": "  //
+    VLOG(1) << "Isomorphic: Final weights not equal to within delta=" << delta_
+            << ": "
             << "fst1.Final(" << s1 << ") = " << fst1_->Final(s1) << ", "
             << "fst2.Final(" << s2 << ") = " << fst2_->Final(s2);
     return false;
@@ -173,34 +187,36 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
     const auto &arc2 = arcs2_[i];
     if (arc1.ilabel != arc2.ilabel) {
       VLOG(1) << "Isomorphic: ilabels not equal. "
-              << "arc1: *" << arc1.ilabel << "* " << arc1.olabel << " "
-              << arc1.weight << " " << arc1.nextstate << "arc2: *"
-              << arc2.ilabel << "* " << arc2.olabel << " " << arc2.weight << " "
-              << arc2.nextstate;
+              << "state1: " << s1 << " arc1: *" << arc1.ilabel << "* "
+              << arc1.olabel << " " << arc1.weight << " " << arc1.nextstate
+              << " state2: " << s2 << " arc2: *" << arc2.ilabel << "* "
+              << arc2.olabel << " " << arc2.weight << " " << arc2.nextstate;
       return false;
     }
     if (arc1.olabel != arc2.olabel) {
       VLOG(1) << "Isomorphic: olabels not equal. "
-              << "arc1: " << arc1.ilabel << " *" << arc1.olabel << "* "
-              << arc1.weight << " " << arc1.nextstate << "arc2: " << arc2.ilabel
-              << " *" << arc2.olabel << "* " << arc2.weight << " "
-              << arc2.nextstate;
+              << "state1: " << s1 << " arc1: " << arc1.ilabel << " *"
+              << arc1.olabel << "* " << arc1.weight << " " << arc1.nextstate
+              << " state2: " << s2 << " arc2: " << arc2.ilabel << " *"
+              << arc2.olabel << "* " << arc2.weight << " " << arc2.nextstate;
       return false;
     }
     if (!ApproxEqual(arc1.weight, arc2.weight, delta_)) {
       VLOG(1) << "Isomorphic: weights not ApproxEqual. "
-              << "arc1: " << arc1.ilabel << " " << arc1.olabel << " *"
-              << arc1.weight << "* " << arc1.nextstate
-              << "arc2: " << arc2.ilabel << " " << arc2.olabel << " *"
-              << arc2.weight << "* " << arc2.nextstate;
+              << "state1: " << s1 << " arc1: " << arc1.ilabel << " "
+              << arc1.olabel << " *" << arc1.weight << "* " << arc1.nextstate
+              << " state2: " << s2 << " arc2: " << arc2.ilabel << " "
+              << arc2.olabel << " *" << arc2.weight << "* " << arc2.nextstate;
       return false;
     }
     if (!PairState(arc1.nextstate, arc2.nextstate)) {
       VLOG(1) << "Isomorphic: nextstates could not be paired. "
-              << "arc1: " << arc1.ilabel << " " << arc1.olabel << " "
-              << arc1.weight << " *" << arc1.nextstate
-              << "* arc2: " << arc2.ilabel << " " << arc2.olabel << " "
-              << arc2.weight << " *" << arc2.nextstate << "*";
+              << "state1: " << s1 << " arc1: " << arc1.ilabel << " "
+              << arc1.olabel << " " << arc1.weight << " *" << arc1.nextstate
+              << "* "
+              << "state2: " << s2 << " arc2: " << arc2.ilabel << " "
+              << arc2.olabel << " " << arc2.weight << " *" << arc2.nextstate
+              << "*";
       return false;
     }
     if (i > 0) {  // Checks for non-determinism.
@@ -212,9 +228,9 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
         // states of nondeterministic transitions.
         VLOG(1) << "Isomorphic: Detected non-determinism as an unweighted "
                 << "automaton; deferring error. "
-                << "arc1: " << arc1.ilabel << " " << arc1.olabel << " "
-                << arc1.weight << " " << arc1.nextstate
-                << "arc2: " << arc2.ilabel << " " << arc2.olabel << " "
+                << "state: " << s1 << " arc1: " << arc1.ilabel << " "
+                << arc1.olabel << " " << arc1.weight << " " << arc1.nextstate
+                << " arc2: " << arc2.ilabel << " " << arc2.olabel << " "
                 << arc2.weight << " " << arc2.nextstate;
         nondet_ = true;
       }
@@ -226,7 +242,7 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
 }  // namespace internal
 
 // Tests if two FSTs have the same states and arcs up to a reordering.
-// Inputs should be nondeterministic when viewed as unweighted automata.
+// Inputs should be deterministic when viewed as unweighted automata.
 // When the inputs are nondeterministic, the algorithm only considers one
 // permutation for each set of equivalent nondeterministic transitions
 // (the permutation that preserves state ID ordering) and hence might return
index 963fa04..b9414ba 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 9ccd562..ed5750c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -28,6 +42,9 @@ namespace fst {
 template <class W1, class W2>
 class LexicographicWeight : public PairWeight<W1, W2> {
  public:
+  static_assert(IsPath<W1>::value, "W1 must have path property.");
+  static_assert(IsPath<W2>::value, "W2 must have path property.");
+
   using ReverseWeight = LexicographicWeight<typename W1::ReverseWeight,
                                             typename W2::ReverseWeight>;
 
@@ -46,18 +63,7 @@ class LexicographicWeight : public PairWeight<W1, W2> {
   explicit LexicographicWeight(const PairWeight<W1, W2> &w)
       : PairWeight<W1, W2>(w) {}
 
-  LexicographicWeight(W1 w1, W2 w2) : PairWeight<W1, W2>(w1, w2) {
-    if ((W1::Properties() & kPath) != kPath) {
-      FSTERROR() << "LexicographicWeight must "
-                 << "have the path property: " << W1::Type();
-      SetValue1(W1::NoWeight());
-    }
-    if ((W2::Properties() & kPath) != kPath) {
-      FSTERROR() << "LexicographicWeight must "
-                 << "have the path property: " << W2::Type();
-      SetValue2(W2::NoWeight());
-    }
-  }
+  LexicographicWeight(W1 w1, W2 w2) : PairWeight<W1, W2>(w1, w2) {}
 
   static const LexicographicWeight &Zero() {
     static const LexicographicWeight zero(PairWeight<W1, W2>::Zero());
index 6780343..332092b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 99570e3..e3fba9c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -633,7 +647,7 @@ inline bool LabelLookAheadMatcher<M, flags, Accumulator,
   return reach_arc || reach_final;
 }
 
-// Relabels the fst with Reachable::Reachable.  Relabels input
+// Relabels the fst with Reachable::Reachable. Relabels input
 // if data.First() is non-null, otherwise relabels output.
 // Optionally saves the input/output label pairs to a file
 // if save_relabel_ipairs/opairs is non-empty.
@@ -709,7 +723,7 @@ inline LabelLookAheadRelabeler<Arc, Data>::LabelLookAheadRelabeler(
     // Borrow pointer from fst without increasing ref count; it will
     // be released below. We do not want to call Copy() since that would
     // do a deep copy when the Fst is modified.
-    mfst.reset(static_cast<MutableFst<Arc> *>(&fst));
+    mfst.reset(fst::down_cast<MutableFst<Arc> *>(&fst));
   } else {
     mfst = fst::make_unique<VectorFst<Arc>>(fst);
   }
@@ -782,7 +796,7 @@ class LookAheadMatcher {
 
   ssize_t Priority(StateId s) { return base_->Priority(s); }
 
-  const FST &GetFst() const { return static_cast<const FST &>(base_->GetFst()); }
+  const FST &GetFst() const { return fst::down_cast<const FST &>(base_->GetFst()); }
 
   uint64 Properties(uint64 props) const { return base_->Properties(props); }
 
@@ -790,7 +804,7 @@ class LookAheadMatcher {
 
   bool LookAheadLabel(Label label) const {
     if (LookAheadCheck()) {
-      return static_cast<LBase *>(base_.get())->LookAheadLabel(label);
+      return fst::down_cast<LBase *>(base_.get())->LookAheadLabel(label);
     } else {
       return true;
     }
@@ -798,7 +812,7 @@ class LookAheadMatcher {
 
   bool LookAheadFst(const Fst<Arc> &fst, StateId s) {
     if (LookAheadCheck()) {
-      return static_cast<LBase *>(base_.get())->LookAheadFst(fst, s);
+      return fst::down_cast<LBase *>(base_.get())->LookAheadFst(fst, s);
     } else {
       return true;
     }
@@ -806,7 +820,7 @@ class LookAheadMatcher {
 
   Weight LookAheadWeight() const {
     if (LookAheadCheck()) {
-      return static_cast<LBase *>(base_.get())->LookAheadWeight();
+      return fst::down_cast<LBase *>(base_.get())->LookAheadWeight();
     } else {
       return Weight::One();
     }
@@ -814,7 +828,7 @@ class LookAheadMatcher {
 
   bool LookAheadPrefix(Arc *arc) const {
     if (LookAheadCheck()) {
-      return static_cast<LBase *>(base_.get())->LookAheadPrefix(arc);
+      return fst::down_cast<LBase *>(base_.get())->LookAheadPrefix(arc);
     } else {
       return false;
     }
@@ -822,7 +836,7 @@ class LookAheadMatcher {
 
   void InitLookAheadFst(const Fst<Arc> &fst, bool copy = false) {
     if (LookAheadCheck()) {
-      static_cast<LBase *>(base_.get())->InitLookAheadFst(fst, copy);
+      fst::down_cast<LBase *>(base_.get())->InitLookAheadFst(fst, copy);
     }
   }
 
index a47a7f5..4627110 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 
 #include <fst/arc-map.h>
 
-
 namespace fst {
 
 template <class A, class C>
+OPENFST_DEPRECATED("Use `ArcMap` instead.")
 void Map(MutableFst<A> *fst, C *mapper) {
   ArcMap(fst, mapper);
 }
 
 template <class A, class C>
+OPENFST_DEPRECATED("Use `ArcMap` instead.")
 void Map(MutableFst<A> *fst, C mapper) {
   ArcMap(fst, mapper);
 }
 
 template <class A, class B, class C>
+OPENFST_DEPRECATED("Use `ArcMap` instead.")
 void Map(const Fst<A> &ifst, MutableFst<B> *ofst, C *mapper) {
   ArcMap(ifst, ofst, mapper);
 }
 
 template <class A, class B, class C>
+OPENFST_DEPRECATED("Use `ArcMap` instead.")
 void Map(const Fst<A> &ifst, MutableFst<B> *ofst, C mapper) {
   ArcMap(ifst, ofst, mapper);
 }
 
-using MapFstOptions = ArcMapFstOptions;
-
-template <class A, class B, class C>
-class MapFst : public ArcMapFst<A, B, C> {
- public:
-  using FromArc = A;
-  using ToArc = B;
-
-  using StateId = typename ToArc::StateId;
-  using Weight = typename ToArc::Weight;
-
-  using State = CacheState<B>;
-
-  MapFst(const Fst<A> &fst, const C &mapper, const MapFstOptions &opts)
-      : ArcMapFst<A, B, C>(fst, mapper, opts) {}
-
-  MapFst(const Fst<A> &fst, C *mapper, const MapFstOptions &opts)
-      : ArcMapFst<A, B, C>(fst, mapper, opts) {}
+using MapFstOptions OPENFST_DEPRECATED("Use `ArcMapFstOptions` instead.") =
+    ArcMapFstOptions;
 
-  MapFst(const Fst<A> &fst, const C &mapper)
-      : ArcMapFst<A, B, C>(fst, mapper) {}
-
-  MapFst(const Fst<A> &fst, C *mapper) : ArcMapFst<A, B, C>(fst, mapper) {}
-
-  // See Fst<>::Copy() for doc.
-  MapFst(const MapFst &fst, bool safe = false)
-      : ArcMapFst<A, B, C>(fst, safe) {}
-
-  // Get a copy of this MapFst. See Fst<>::Copy() for further doc.
-  MapFst *Copy(bool safe = false) const override {
-    return new MapFst(*this, safe);
-  }
-};
-
-// Specialization for MapFst.
-template <class A, class B, class C>
-class StateIterator<MapFst<A, B, C>>
-    : public StateIterator<ArcMapFst<A, B, C>> {
- public:
-  explicit StateIterator(const ArcMapFst<A, B, C> &fst)
-      : StateIterator<ArcMapFst<A, B, C>>(fst) {}
-};
-
-// Specialization for MapFst.
 template <class A, class B, class C>
-class ArcIterator<MapFst<A, B, C>> : public ArcIterator<ArcMapFst<A, B, C>> {
- public:
-  ArcIterator(const ArcMapFst<A, B, C> &fst, typename A::StateId s)
-      : ArcIterator<ArcMapFst<A, B, C>>(fst, s) {}
-};
+using MapFst OPENFST_DEPRECATED("Use `ArcMapFst` instead.") = ArcMapFst<A, B, C>;
 
-// For backwards compatibility only; use IdentityArcMapper otherwise.
 template <class A>
-struct IdentityMapper {
-  using FromArc = A;
-  using ToArc = A;
-
-  ToArc operator()(const FromArc &arc) const { return arc; }
-
-  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
-
-  constexpr MapSymbolsAction InputSymbolsAction() const {
-    return MAP_COPY_SYMBOLS;
-  }
-
-  constexpr MapSymbolsAction OutputSymbolsAction() const {
-    return MAP_COPY_SYMBOLS;
-  }
-
-  uint64 Properties(uint64 props) const { return props; }
-};
+using IdentityMapper OPENFST_DEPRECATED("Use `IdentityArcMapper` instead.") =
+    IdentityArcMapper<A>;
 
 }  // namespace fst
 
index 8f70700..c182eea 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3d63bd4..55fe5a6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -95,7 +109,7 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
 
   // Constructs a MatcherFst from an Fst<Arc>, which is *not* the underlying
   // FST type used by this class. Uses the existing Data if present, and
-  // runs Init on it.  Stores fst internally, converting Fst<Arc> to FST and
+  // runs Init on it. Stores fst internally, converting Fst<Arc> to FST and
   // therefore making a deep copy.
   explicit MatcherFst(const Fst<Arc> &fst, std::shared_ptr<Data> data = nullptr)
       : ImplToExpandedFst<Impl>(data ? CreateImpl(fst, Name, data)
index de9ed45..fc4f016 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -533,7 +547,7 @@ void HashMatcher<FST>::SetState(typename FST::Arc::StateId s) {
   }
   // Attempts to insert a new label table.
   auto it_and_success = state_table_->emplace(
-      state_, std::unique_ptr<LabelTable>(new LabelTable()));
+      state_, fst::make_unique<LabelTable>());
   // Sets instance's pointer to the label table for this state.
   label_table_ = it_and_success.first->second.get();
   // If it already exists, no additional work is done and we simply return.
@@ -571,14 +585,14 @@ enum MatcherRewriteMode {
 // For any requested label that doesn't match at a state, this matcher
 // considers the *unique* transition that matches the label 'phi_label'
 // (phi = 'fail'), and recursively looks for a match at its
-// destination.  When 'phi_loop' is true, if no match is found but a
+// destination. When 'phi_loop' is true, if no match is found but a
 // phi self-loop is found, then the phi transition found is returned
 // with the phi_label rewritten as the requested label (both sides if
 // an acceptor, or if 'rewrite_both' is true and both input and output
-// labels of the found transition are 'phi_label').  If 'phi_label' is
-// kNoLabel, this special matching is not done.  PhiMatcher is
+// labels of the found transition are 'phi_label'). If 'phi_label' is
+// kNoLabel, this special matching is not done. PhiMatcher is
 // templated itself on a matcher, which is used to perform the
-// underlying matching.  By default, the underlying matcher is
+// underlying matching. By default, the underlying matcher is
 // constructed by PhiMatcher. The user can instead pass in this
 // object; in that case, PhiMatcher takes its ownership.
 // Phi non-determinism not supported. No non-consuming symbols other
@@ -831,14 +845,14 @@ inline uint64 PhiMatcher<M>::Properties(uint64 inprops) const {
 
 // For any requested label that doesn't match at a state, this matcher
 // considers all transitions that match the label 'rho_label' (rho =
-// 'rest').  Each such rho transition found is returned with the
+// 'rest'). Each such rho transition found is returned with the
 // rho_label rewritten as the requested label (both sides if an
 // acceptor, or if 'rewrite_both' is true and both input and output
-// labels of the found transition are 'rho_label').  If 'rho_label' is
-// kNoLabel, this special matching is not done.  RhoMatcher is
+// labels of the found transition are 'rho_label'). If 'rho_label' is
+// kNoLabel, this special matching is not done. RhoMatcher is
 // templated itself on a matcher, which is used to perform the
-// underlying matching.  By default, the underlying matcher is
-// constructed by RhoMatcher.  The user can instead pass in this
+// underlying matching. By default, the underlying matcher is
+// constructed by RhoMatcher. The user can instead pass in this
 // object; in that case, RhoMatcher takes its ownership.
 // No non-consuming symbols other than epsilon supported with
 // the underlying template argument matcher.
@@ -1020,16 +1034,16 @@ inline uint64 RhoMatcher<M>::Properties(uint64 inprops) const {
 
 // For any requested label, this matcher considers all transitions
 // that match the label 'sigma_label' (sigma = "any"), and this in
-// additions to transitions with the requested label.  Each such sigma
+// additions to transitions with the requested label. Each such sigma
 // transition found is returned with the sigma_label rewritten as the
 // requested label (both sides if an acceptor, or if 'rewrite_both' is
 // true and both input and output labels of the found transition are
-// 'sigma_label').  If 'sigma_label' is kNoLabel, this special
-// matching is not done.  SigmaMatcher is templated itself on a
-// matcher, which is used to perform the underlying matching.  By
+// 'sigma_label'). If 'sigma_label' is kNoLabel, this special
+// matching is not done. SigmaMatcher is templated itself on a
+// matcher, which is used to perform the underlying matching. By
 // default, the underlying matcher is constructed by SigmaMatcher.
 // The user can instead pass in this object; in that case,
-// SigmaMatcher takes its ownership.  No non-consuming symbols other
+// SigmaMatcher takes its ownership. No non-consuming symbols other
 // than epsilon supported with the underlying template argument matcher.
 template <class M>
 class SigmaMatcher : public MatcherBase<typename M::Arc> {
@@ -1541,7 +1555,7 @@ class Matcher {
 
   void Next() { base_->Next(); }
 
-  const FST &GetFst() const { return static_cast<const FST &>(base_->GetFst()); }
+  const FST &GetFst() const { return fst::down_cast<const FST &>(base_->GetFst()); }
 
   uint64 Properties(uint64 props) const { return base_->Properties(props); }
 
index 08a7281..6d342f4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -157,7 +171,7 @@ class MemoryArenaCollection {
  public:
   // 'block_size' specifies the block size of the arenas.
   explicit MemoryArenaCollection(size_t block_size = kAllocSize)
-      : block_size_(block_size), ref_count_(1) {}
+      : block_size_(block_size) {}
 
   template <typename T>
   MemoryArena<T> *Arena() {
@@ -172,15 +186,8 @@ class MemoryArenaCollection {
 
   size_t BlockSize() const { return block_size_; }
 
-  size_t RefCount() const { return ref_count_; }
-
-  size_t IncrRefCount() { return ++ref_count_; }
-
-  size_t DecrRefCount() { return --ref_count_; }
-
  private:
   size_t block_size_;
-  size_t ref_count_;
   std::vector<std::unique_ptr<MemoryArenaBase>> arenas_;
 };
 
@@ -189,7 +196,7 @@ class MemoryPoolCollection {
  public:
   // 'pool_size' specifies the size of initial pool and how it is extended.
   explicit MemoryPoolCollection(size_t pool_size = kAllocSize)
-      : pool_size_(pool_size), ref_count_(1) {}
+      : pool_size_(pool_size) {}
 
   template <typename T>
   MemoryPool<T> *Pool() {
@@ -204,15 +211,8 @@ class MemoryPoolCollection {
 
   size_t PoolSize() const { return pool_size_; }
 
-  size_t RefCount() const { return ref_count_; }
-
-  size_t IncrRefCount() { return ++ref_count_; }
-
-  size_t DecrRefCount() { return --ref_count_; }
-
  private:
   size_t pool_size_;
-  size_t ref_count_;
   std::vector<std::unique_ptr<MemoryPoolBase>> pools_;
 };
 
@@ -243,22 +243,17 @@ class BlockAllocator {
   };
 
   explicit BlockAllocator(size_t block_size = kAllocSize)
-      : arenas_(new MemoryArenaCollection(block_size)) {}
+      : arenas_(std::make_shared<MemoryArenaCollection>(block_size)) {}
 
-  BlockAllocator(const BlockAllocator<T> &arena_alloc)
-      : arenas_(arena_alloc.Arenas()) {
-    Arenas()->IncrRefCount();
-  }
+  ~BlockAllocator() = default;
+  BlockAllocator(const BlockAllocator &) = default;
+  BlockAllocator(BlockAllocator &&) = default;
+  BlockAllocator &operator=(const BlockAllocator &) = default;
+  BlockAllocator &operator=(BlockAllocator &&) = default;
 
   template <typename U>
   explicit BlockAllocator(const BlockAllocator<U> &arena_alloc)
-      : arenas_(arena_alloc.Arenas()) {
-    Arenas()->IncrRefCount();
-  }
-
-  ~BlockAllocator() {
-    if (Arenas()->DecrRefCount() == 0) delete Arenas();
-  }
+      : arenas_(arena_alloc.Arenas()) {}
 
   pointer address(reference ref) const { return Allocator().address(ref); }
 
@@ -287,14 +282,12 @@ class BlockAllocator {
     if (n * kAllocFit > kAllocSize) Allocator().deallocate(p, n);
   }
 
-  MemoryArenaCollection *Arenas() const { return arenas_; }
+  std::shared_ptr<MemoryArenaCollection> Arenas() const { return arenas_; }
 
  private:
   MemoryArena<T> *Arena() { return arenas_->Arena<T>(); }
 
-  MemoryArenaCollection *arenas_;
-
-  BlockAllocator<T> operator=(const BlockAllocator &);
+  std::shared_ptr<MemoryArenaCollection> arenas_;
 };
 
 template <typename T, typename U>
@@ -335,22 +328,17 @@ class PoolAllocator {
   };
 
   explicit PoolAllocator(size_t pool_size = kAllocSize)
-      : pools_(new MemoryPoolCollection(pool_size)) {}
+      : pools_(std::make_shared<MemoryPoolCollection>(pool_size)) {}
 
-  PoolAllocator(const PoolAllocator<T> &pool_alloc)
-      : pools_(pool_alloc.Pools()) {
-    Pools()->IncrRefCount();
-  }
+  ~PoolAllocator() = default;
+  PoolAllocator(const PoolAllocator &) = default;
+  PoolAllocator(PoolAllocator &&) = default;
+  PoolAllocator &operator=(const PoolAllocator &) = default;
+  PoolAllocator &operator=(PoolAllocator &&) = default;
 
   template <typename U>
   explicit PoolAllocator(const PoolAllocator<U> &pool_alloc)
-      : pools_(pool_alloc.Pools()) {
-    Pools()->IncrRefCount();
-  }
-
-  ~PoolAllocator() {
-    if (Pools()->DecrRefCount() == 0) delete Pools();
-  }
+      : pools_(pool_alloc.Pools()) {}
 
   pointer address(reference ref) const { return Allocator().address(ref); }
 
@@ -407,7 +395,7 @@ class PoolAllocator {
     }
   }
 
-  MemoryPoolCollection *Pools() const { return pools_; }
+  std::shared_ptr<MemoryPoolCollection> Pools() const { return pools_; }
 
  private:
   template <int n>
@@ -420,9 +408,7 @@ class PoolAllocator {
     return pools_->Pool<TN<n>>();
   }
 
-  MemoryPoolCollection *pools_;
-
-  PoolAllocator<T> operator=(const PoolAllocator &);
+  std::shared_ptr<MemoryPoolCollection> pools_;
 };
 
 template <typename T, typename U>
index b1a9766..e6c6856 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e5266a0..6351044 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -11,6 +25,7 @@
 
 #include <cstddef>
 #include <istream>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -126,7 +141,7 @@ class MutableFst : public ExpandedFst<A> {
     }
     auto *fst = reader(strm, ropts);
     if (!fst) return nullptr;
-    return static_cast<MutableFst *>(fst);
+    return fst::down_cast<MutableFst *>(fst);
   }
 
   // Reads a MutableFst from a file; returns nullptr on error. An empty
@@ -151,7 +166,7 @@ class MutableFst : public ExpandedFst<A> {
       std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(source));
       if (!ifst) return nullptr;
       if (ifst->Properties(kMutable, false)) {
-        return static_cast<MutableFst *>(ifst.release());
+        return fst::down_cast<MutableFst *>(ifst.release());
       } else {
         std::unique_ptr<Fst<Arc>> ofst(Convert(*ifst, convert_type));
         ifst.reset();
@@ -159,7 +174,7 @@ class MutableFst : public ExpandedFst<A> {
         if (!ofst->Properties(kMutable, false)) {
           LOG(ERROR) << "MutableFst: Bad convert type: " << convert_type;
         }
-        return static_cast<MutableFst *>(ofst.release());
+        return fst::down_cast<MutableFst *>(ofst.release());
       }
     }
   }
@@ -182,7 +197,7 @@ class MutableArcIteratorBase : public ArcIteratorBase<Arc> {
 
 template <class Arc>
 struct MutableArcIteratorData {
-  MutableArcIteratorBase<Arc> *base;  // Specific iterator.
+  std::unique_ptr<MutableArcIteratorBase<Arc>> base;  // Specific iterator.
 };
 
 // Generic mutable arc iterator, templated on the FST definition; a wrapper
@@ -210,8 +225,6 @@ class MutableArcIterator {
     fst->InitMutableArcIterator(s, &data_);
   }
 
-  ~MutableArcIterator() { delete data_.base; }
-
   bool Done() const { return data_.base->Done(); }
 
   const Arc &Value() const { return data_.base->Value(); }
index 5b71282..73b3438 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 5dbbe46..ebcfee2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -33,7 +47,7 @@ class PartitionIterator;
 //
 // We also support a rather specialized interface that allows you to efficiently
 // split classes in the Hopcroft minimization algorithm. This maintains a
-// binary partition of each class.  Let's call these, rather arbitrarily, the
+// binary partition of each class. Let's call these, rather arbitrarily, the
 // 'yes' subset and the 'no' subset of each class, and assume that by default,
 // each element of a class is in its 'no' subset. When one calls
 // SplitOn(element_id), element_id is moved to the 'yes' subset of its class.
index 1884bfe..36fe15d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e1f9a3f..30cb4e6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index fab1657..d3f5902 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index ae96322..c5c7a5f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 1f0ec1d..0aa4fa5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -361,7 +375,7 @@ uint64 ReplaceProperties(const std::vector<uint64> &inprops, size_t root,
 
 uint64 ReverseProperties(uint64 inprops, bool has_superinitial);
 
-uint64 ReweightProperties(uint64 inprops);
+uint64 ReweightProperties(uint64 inprops, bool added_start_epsilon);
 
 uint64 RmEpsilonProperties(uint64 inprops, bool delayed = false);
 
index 387bca2..7364c32 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -212,7 +226,7 @@ void Prune(MutableFst<Arc> *fst, typename Arc::Weight weight_threshold,
 // shortest path Times() the provided weight threshold. When the state
 // threshold is not kNoStateId, the output FST is further restricted
 // to have no more than the number of states in
-// opts.state_threshold. Weights have the path property.  The weight
+// opts.state_threshold. Weights have the path property. The weight
 // of any cycle needs to be bounded; i.e.,
 //
 //   Plus(weight, Weight::One()) == Weight::One()
index 429b5e6..6c5f856 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 05e978b..64a4f2c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -263,27 +277,36 @@ class StateWeightCompare {
   const Less &less_;
 };
 
+// Comparison that can never be instantiated. Useful only to pass a pointer to
+// this to a function that needs a comparison when it is known that the pointer
+// will always be null.
+template <class W>
+struct ErrorLess {
+  using Weight = W;
+  ErrorLess() {
+    FSTERROR() << "ErrorLess: instantiated for Weight " << Weight::Type();
+  }
+  bool operator()(const Weight &, const Weight &) const { return false; }
+};
+
 }  // namespace internal
 
 // Shortest-first queue discipline, templated on the StateId and Weight, is
 // specialized to use the weight's natural order for the comparison function.
+// Requires Weight is idempotent (due to use of NaturalLess).
 template <typename S, typename Weight>
 class NaturalShortestFirstQueue
     : public ShortestFirstQueue<
           S, internal::StateWeightCompare<S, NaturalLess<Weight>>> {
  public:
   using StateId = S;
-  using Compare = internal::StateWeightCompare<StateId, NaturalLess<Weight>>;
+  using Less = NaturalLess<Weight>;
+  using Compare = internal::StateWeightCompare<StateId, Less>;
 
   explicit NaturalShortestFirstQueue(const std::vector<Weight> &distance)
-      : ShortestFirstQueue<StateId, Compare>(Compare(distance, less_)) {}
+      : ShortestFirstQueue<StateId, Compare>(Compare(distance, Less())) {}
 
   ~NaturalShortestFirstQueue() override = default;
-
- private:
-  // This is non-static because the constructor for non-idempotent weights will
-  // result in an error.
-  const NaturalLess<Weight> less_{};
 };
 
 // In a shortest path computation on a lattice-like FST, we may keep many old
@@ -617,7 +640,11 @@ class AutoQueue : public QueueBase<S> {
             const std::vector<typename Arc::Weight> *distance, ArcFilter filter)
       : QueueBase<StateId>(AUTO_QUEUE) {
     using Weight = typename Arc::Weight;
-    using Less = NaturalLess<Weight>;
+    // We need to have variables of type Less and Compare, so we use
+    // ErrorLess if the type NaturalLess<Weight> cannot be instantiated due
+    // to lack of path property.
+    using Less = std::conditional_t<IsPath<Weight>::value, NaturalLess<Weight>,
+                                    internal::ErrorLess<Weight>>;
     using Compare = internal::StateWeightCompare<StateId, Less>;
     // First checks if the FST is known to have these properties.
     const auto props =
@@ -640,9 +667,11 @@ class AutoQueue : public QueueBase<S> {
       std::vector<QueueType> queue_types(nscc);
       std::unique_ptr<Less> less;
       std::unique_ptr<Compare> comp;
-      if (distance && (Weight::Properties() & kPath) == kPath) {
-        less = fst::make_unique<Less>();
-        comp = fst::make_unique<Compare>(*distance, *less);
+      if constexpr (IsPath<Weight>::value) {
+        if (distance) {
+          less = fst::make_unique<Less>();
+          comp = fst::make_unique<Compare>(*distance, *less);
+        }
       }
       // Finds the queue type to use per SCC.
       bool unweighted;
@@ -671,10 +700,19 @@ class AutoQueue : public QueueBase<S> {
             VLOG(3) << "AutoQueue: SCC #" << i << ": using trivial discipline";
             break;
           case SHORTEST_FIRST_QUEUE:
-            queues_[i].reset(
-                new ShortestFirstQueue<StateId, Compare, false>(*comp));
-            VLOG(3) << "AutoQueue: SCC #" << i
-                    << ": using shortest-first discipline";
+            // The IsPath test is not needed for correctness. It just saves
+            // instantiating a ShortestFirstQueue that can never be called.
+            if constexpr (IsPath<Weight>::value) {
+              queues_[i].reset(
+                  new ShortestFirstQueue<StateId, Compare, false>(*comp));
+              VLOG(3) << "AutoQueue: SCC #" << i
+                      << ": using shortest-first discipline";
+            } else {
+              // SccQueueType should ensure this can never happen.
+              FSTERROR() << "Got SHORTEST_FIRST_QUEUE for non-Path Weight "
+                         << Weight::Type();
+              queues_[i].reset();
+            }
             break;
           case LIFO_QUEUE:
             queues_[i] = fst::make_unique<LifoQueue<StateId>>();
@@ -746,7 +784,9 @@ void AutoQueue<StateId>::SccQueueType(const Fst<Arc> &fst,
       if (!filter(arc)) continue;
       if (scc[state] == scc[arc.nextstate]) {
         auto &type = (*queue_type)[scc[state]];
-        if (!less || ((*less)(arc.weight, Weight::One()))) {
+        if constexpr (!IsPath<Weight>::value) {
+          type = FIFO_QUEUE;
+        } else if (!less || (*less)(arc.weight, Weight::One())) {
           type = FIFO_QUEUE;
         } else if ((type == TRIVIAL_QUEUE) || (type == LIFO_QUEUE)) {
           if (!(Weight::Properties() & kIdempotent) ||
index 55d45d6..f903302 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 2fe1af5..4ebb752 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -261,7 +275,7 @@ template <class Result, class RNG>
 void OneMultinomialSample(const std::vector<double> &probs,
                           size_t num_to_sample, Result *result, RNG *rng) {
   using distribution = std::binomial_distribution<size_t>;
-  // Left-over probability mass.  Keep an array of the partial sums because
+  // Left-over probability mass. Keep an array of the partial sums because
   // keeping a scalar and modifying norm -= probs[i] in the loop will result
   // in round-off error and can have probs[i] > norm.
   std::vector<double> norm(probs.size());
@@ -631,7 +645,9 @@ class ArcIterator<RandGenFst<FromArc, ToArc, Sampler>>
 template <class FromArc, class ToArc, class Sampler>
 inline void RandGenFst<FromArc, ToArc, Sampler>::InitStateIterator(
     StateIteratorData<ToArc> *data) const {
-  data->base = new StateIterator<RandGenFst<FromArc, ToArc, Sampler>>(*this);
+  data->base =
+      fst::make_unique<StateIterator<RandGenFst<FromArc, ToArc, Sampler>>>(
+          *this);
 }
 
 // Options for random path generation.
index e86371f..a8c1322 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 24bac15..4fd9996 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -91,7 +105,14 @@ class FstRegisterer : public GenericRegisterer<FstRegister<typename FST::Arc>> {
   static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new FST(fst); }
 };
 
-// Convenience macro to generate static FstRegisterer instance.
+// Convenience macro to generate a static FstRegisterer instance.
+// `FST` and `Arc` must be identifiers (that is, not a qualified type).
+// Users SHOULD NOT register within the fst namespace. To register an
+// FST for StdArc, for example, use:
+// namespace example {
+// using fst::StdArc;
+// REGISTER_FST(MyFst, StdArc);
+// }  // namespace example
 #define REGISTER_FST(FST, Arc) \
   static fst::FstRegisterer<FST<Arc>> FST##_##Arc##_registerer
 
index b7a99d6..24fd2fd 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -17,7 +31,6 @@
 #include <fst/cache.h>
 #include <fst/test-properties.h>
 
-
 #include <unordered_map>
 
 namespace fst {
@@ -45,6 +58,10 @@ void Relabel(
     for (MutableArcIterator<MutableFst<Arc>> aiter(fst, siter.Value());
          !aiter.Done(); aiter.Next()) {
       auto arc = aiter.Value();
+      // dense_hash_map does not support find on the empty_key_val.
+      // These labels should never be in an FST anyway.
+      DCHECK_NE(arc.ilabel, kNoLabel);
+      DCHECK_NE(arc.olabel, kNoLabel);
       // Relabels input.
       auto it = input_map.find(arc.ilabel);
       if (it != input_map.end()) {
@@ -452,7 +469,7 @@ class ArcIterator<RelabelFst<Arc>> : public CacheArcIterator<RelabelFst<Arc>> {
 template <class Arc>
 inline void RelabelFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<RelabelFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<RelabelFst<Arc>>>(*this);
 }
 
 // Useful alias when using StdArc.
index ed83f53..ef73ae6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 747931f..4e00b4d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -934,7 +948,7 @@ class ReplaceFstImpl
 //
 // Observe that Matcher<Fst<A>> will use the optionally caching arc iterator
 // when available (the FST is ilabel-sorted and matching on the input, or the
-// FST is olabel -orted and matching on the output).  In order to obtain the
+// FST is olabel -orted and matching on the output). In order to obtain the
 // most efficient behaviour, it is recommended to set call_label_type to
 // REPLACE_LABEL_INPUT or REPLACE_LABEL_BOTH and return_label_type to
 // REPLACE_LABEL_OUTPUT or REPLACE_LABEL_NEITHER. This means that the call arc
@@ -1431,7 +1445,8 @@ template <class Arc, class StateTable, class CacheStore>
 inline void ReplaceFst<Arc, StateTable, CacheStore>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
   data->base =
-      new StateIterator<ReplaceFst<Arc, StateTable, CacheStore>>(*this);
+      fst::make_unique<StateIterator<ReplaceFst<Arc, StateTable, CacheStore>>>(
+          *this);
 }
 
 using StdReplaceFst = ReplaceFst<StdArc>;
index 0bbe29b..de3e4e5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index af8aa12..f7a662f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -11,6 +25,7 @@
 #include <fst/log.h>
 
 #include <fst/mutable-fst.h>
+#include <fst/properties.h>
 
 
 namespace fst {
@@ -49,6 +64,7 @@ void Reweight(MutableFst<Arc> *fst,
     fst->SetProperties(kError, kError);
     return;
   }
+  const uint64 input_props = fst->Properties(kFstProperties, false);
   StateIterator<MutableFst<Arc>> siter(*fst);
   for (; !siter.Done(); siter.Next()) {
     const auto s = siter.Value();
@@ -89,6 +105,7 @@ void Reweight(MutableFst<Arc> *fst,
   const auto startweight = fst->Start() < potential.size()
                                ? potential[fst->Start()]
                                : Weight::Zero();
+  bool added_start_epsilon = false;
   if ((startweight != Weight::One()) && (startweight != Weight::Zero())) {
     if (fst->Properties(kInitialAcyclic, true) & kInitialAcyclic) {
       const auto s = fst->Start();
@@ -117,9 +134,11 @@ void Reweight(MutableFst<Arc> *fst,
               : Divide(Weight::One(), startweight, DIVIDE_RIGHT);
       fst->AddArc(s, Arc(0, 0, weight, fst->Start()));
       fst->SetStart(s);
+      added_start_epsilon = true;
     }
   }
-  fst->SetProperties(ReweightProperties(fst->Properties(kFstProperties, false)),
+  fst->SetProperties(ReweightProperties(input_props, added_start_epsilon) |
+                     fst->Properties(kFstProperties, false),
                      kFstProperties);
 }
 
index a9addd5..d171a5e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -543,7 +557,7 @@ class ArcIterator<RmEpsilonFst<Arc>>
 template <class Arc>
 inline void RmEpsilonFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<RmEpsilonFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<RmEpsilonFst<Arc>>>(*this);
 }
 
 // Useful alias when using StdArc.
index 0953bcc..ca67c96 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 7febb0d..4f3836a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 8f6859d..d5b538c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 85c3876..b7f0d52 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 
 #include <utility>
 
+#include <fst/types.h>
 #include <fst/arcsort.h>
 #include <fst/script/fst-class.h>
 
 namespace fst {
 namespace script {
 
-enum ArcSortType { ILABEL_SORT, OLABEL_SORT };
+enum class ArcSortType : uint8 { ILABEL, OLABEL };
 
 using ArcSortArgs = std::pair<MutableFstClass *, ArcSortType>;
 
@@ -20,12 +35,12 @@ template <class Arc>
 void ArcSort(ArcSortArgs *args) {
   MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
   switch (std::get<1>(*args)) {
-    case ILABEL_SORT: {
+    case ArcSortType::ILABEL: {
       const ILabelCompare<Arc> icomp;
       ArcSort(fst, icomp);
       return;
     }
-    case OLABEL_SORT: {
+    case ArcSortType::OLABEL: {
       const OLabelCompare<Arc> ocomp;
       ArcSort(fst, ocomp);
       return;
index 93cd4a0..f4d819f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 7c68604..4b48077 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 18ab237..ed1c18a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -36,7 +50,7 @@ class FstCompiler {
   // symbol tables. This is only useful if you set the (i/o)keep flag to attach
   // the final symbol table, or use the accessors. (The input symbol tables are
   // const and therefore not changed.)
-  FstCompiler(std::istream &istrm, const std::string &source,  // NOLINT
+  FstCompiler(std::istream &istrm, const std::string &source,
               const SymbolTable *isyms, const SymbolTable *osyms,
               const SymbolTable *ssyms, bool accep, bool ikeep, bool okeep,
               bool nkeep, bool allow_negative_labels = false) {
@@ -47,7 +61,7 @@ class FstCompiler {
          okeep, nkeep, allow_negative_labels, false);
   }
 
-  FstCompiler(std::istream &istrm, const std::string &source,  // NOLINT
+  FstCompiler(std::istream &istrm, const std::string &source,
               SymbolTable *isyms, SymbolTable *osyms, SymbolTable *ssyms,
               bool accep, bool ikeep, bool okeep, bool nkeep,
               bool allow_negative_labels, bool add_symbols) {
@@ -55,10 +69,10 @@ class FstCompiler {
          allow_negative_labels, add_symbols);
   }
 
-  void Init(std::istream &istrm, const std::string &source,  // NOLINT
-            SymbolTable *isyms, SymbolTable *osyms, SymbolTable *ssyms,
-            bool accep, bool ikeep, bool okeep, bool nkeep,
-            bool allow_negative_labels, bool add_symbols) {
+  void Init(std::istream &istrm, const std::string &source, SymbolTable *isyms,
+            SymbolTable *osyms, SymbolTable *ssyms, bool accep, bool ikeep,
+            bool okeep, bool nkeep, bool allow_negative_labels,
+            bool add_symbols) {
     nline_ = 0;
     source_ = source;
     isyms_ = isyms;
index c588f8e..3e7265d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -35,28 +49,10 @@ struct CompileFstInnerArgs {
   const bool okeep;
   const bool nkeep;
   const bool allow_negative_labels;
-
-  CompileFstInnerArgs(std::istream &istrm, const std::string &source,
-                      const std::string &fst_type,
-                      const fst::SymbolTable *isyms,
-                      const fst::SymbolTable *osyms,
-                      const fst::SymbolTable *ssyms, bool accep, bool ikeep,
-                      bool okeep, bool nkeep,
-                      bool allow_negative_labels = false)
-      : istrm(istrm),
-        source(source),
-        fst_type(fst_type),
-        isyms(isyms),
-        osyms(osyms),
-        ssyms(ssyms),
-        accep(accep),
-        ikeep(ikeep),
-        okeep(okeep),
-        nkeep(nkeep),
-        allow_negative_labels(allow_negative_labels) {}
 };
 
-using CompileFstArgs = WithReturnValue<FstClass *, CompileFstInnerArgs>;
+using CompileFstArgs =
+    WithReturnValue<std::unique_ptr<FstClass>, CompileFstInnerArgs>;
 
 template <class Arc>
 void CompileFstInternal(CompileFstArgs *args) {
@@ -67,17 +63,19 @@ void CompileFstInternal(CompileFstArgs *args) {
       args->args.istrm, args->args.source, args->args.isyms, args->args.osyms,
       args->args.ssyms, args->args.accep, args->args.ikeep, args->args.okeep,
       args->args.nkeep, args->args.allow_negative_labels);
-  const Fst<Arc> *fst = &fstcompiler.Fst();
-  std::unique_ptr<const Fst<Arc>> owned_fst;
+  std::unique_ptr<Fst<Arc>> fst;
   if (args->args.fst_type != "vector") {
-    owned_fst.reset(Convert<Arc>(*fst, args->args.fst_type));
-    if (!owned_fst) {
+    std::unique_ptr<Fst<Arc>> tmp_fst(
+        Convert<Arc>(fstcompiler.Fst(), args->args.fst_type));
+    if (!tmp_fst) {
       FSTERROR() << "Failed to convert FST to desired type: "
                  << args->args.fst_type;
     }
-    fst = owned_fst.get();
+    fst = std::move(tmp_fst);
+  } else {
+    fst = fst::WrapUnique(fstcompiler.Fst().Copy());
   }
-  args->retval = fst ? new FstClass(*fst) : nullptr;
+  args->retval = fst ? fst::make_unique<FstClass>(std::move(fst)) : nullptr;
 }
 
 void CompileFst(std::istream &istrm, const std::string &source,
@@ -86,13 +84,11 @@ void CompileFst(std::istream &istrm, const std::string &source,
                 const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
                 bool ikeep, bool okeep, bool nkeep, bool allow_negative_labels);
 
-FstClass *CompileFstInternal(std::istream &istrm, const std::string &source,
-                             const std::string &fst_type,
-                             const std::string &arc_type,
-                             const SymbolTable *isyms, const SymbolTable *osyms,
-                             const SymbolTable *ssyms, bool accep, bool ikeep,
-                             bool okeep, bool nkeep,
-                             bool allow_negative_labels);
+std::unique_ptr<FstClass> CompileFstInternal(
+    std::istream &istrm, const std::string &source, const std::string &fst_type,
+    const std::string &arc_type, const SymbolTable *isyms,
+    const SymbolTable *osyms, const SymbolTable *ssyms, bool accep, bool ikeep,
+    bool okeep, bool nkeep, bool allow_negative_labels);
 
 }  // namespace script
 }  // namespace fst
index 9ffd604..3b29b3c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f9dd0fe..a71e5a1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 030102a..344735b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f3c03f0..af03215 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -17,17 +31,20 @@ namespace script {
 
 using ConvertInnerArgs = std::pair<const FstClass &, const std::string &>;
 
-using ConvertArgs = WithReturnValue<FstClass *, ConvertInnerArgs>;
+using ConvertArgs =
+    WithReturnValue<std::unique_ptr<FstClass>, ConvertInnerArgs>;
 
 template <class Arc>
 void Convert(ConvertArgs *args) {
   const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
   const std::string &new_type = std::get<1>(args->args);
   std::unique_ptr<Fst<Arc>> result(Convert(fst, new_type));
-  args->retval = result ? new FstClass(*result) : nullptr;
+  args->retval =
+      result ? fst::make_unique<FstClass>(std::move(result)) : nullptr;
 }
 
-FstClass *Convert(const FstClass &fst, const std::string &new_type);
+std::unique_ptr<FstClass> Convert(const FstClass &fst,
+                                  const std::string &new_type);
 
 }  // namespace script
 }  // namespace fst
index 81b9554..c3913dd 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 90fcfd4..209ddf9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index c06d0c7..372eff6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 936295c..6d00224 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a463bc7..bd31e95 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 19686cf..445c290 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -30,35 +44,10 @@ struct DrawArgs {
   const float nodesep;
   const int fontsize;
   const int precision;
-  const std::string &float_format;  // NOLINT
+  const std::string &float_format;
   const bool show_weight_one;
   std::ostream &ostrm;
   const std::string &dest;
-
-  DrawArgs(const FstClass &fst, const SymbolTable *isyms,
-           const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-           const std::string &title, float width, float height, bool portrait,
-           bool vertical, float ranksep, float nodesep, int fontsize,
-           int precision, const std::string &float_format, bool show_weight_one,
-           std::ostream &ostrm, const std::string &dest)
-      : fst(fst),
-        isyms(isyms),
-        osyms(osyms),
-        ssyms(ssyms),
-        accep(accep),
-        title(title),
-        width(width),
-        height(height),
-        portrait(portrait),
-        vertical(vertical),
-        ranksep(ranksep),
-        nodesep(nodesep),
-        fontsize(fontsize),
-        precision(precision),
-        float_format(float_format),
-        show_weight_one(show_weight_one),
-        ostrm(ostrm),
-        dest(dest) {}
 };
 
 template <class Arc>
index 0d79161..fff0ef5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e8dae66..2a4e77e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -165,7 +179,7 @@ class EncodeMapperClass {
     if (Arc::Type() != ArcType()) {
       return nullptr;
     } else {
-      auto *typed_impl = static_cast<EncodeMapperClassImpl<Arc> *>(impl_.get());
+      auto *typed_impl = fst::down_cast<EncodeMapperClassImpl<Arc> *>(impl_.get());
       return typed_impl->GetImpl();
     }
   }
@@ -175,7 +189,7 @@ class EncodeMapperClass {
     if (Arc::Type() != ArcType()) {
       return nullptr;
     } else {
-      auto *typed_impl = static_cast<EncodeMapperClassImpl<Arc> *>(impl_.get());
+      auto *typed_impl = fst::down_cast<EncodeMapperClassImpl<Arc> *>(impl_.get());
       return typed_impl->GetImpl();
     }
   }
index 6648de2..e704de5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 18f8b30..5236c40 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d88fb04..ef42957 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 92d45a3..505fa2d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -7,6 +21,7 @@
 #include <algorithm>
 #include <istream>
 #include <limits>
+#include <memory>
 #include <string>
 #include <type_traits>
 
@@ -84,8 +99,8 @@ class FstClassImplBase : public FstClassBase {
 template <class Arc>
 class FstClassImpl : public FstClassImplBase {
  public:
-  explicit FstClassImpl(Fst<Arc> *impl, bool should_own = false)
-      : impl_(should_own ? impl : impl->Copy()) {}
+  explicit FstClassImpl(std::unique_ptr<Fst<Arc>> impl)
+      : impl_(std::move(impl)) {}
 
   explicit FstClassImpl(const Fst<Arc> &impl) : impl_(impl.Copy()) {}
 
@@ -97,35 +112,35 @@ class FstClassImpl : public FstClassImplBase {
     // used to determine whether any arc has a nonexisting destination.
     Arc arc(ac.ilabel, ac.olabel, *ac.weight.GetWeight<typename Arc::Weight>(),
             ac.nextstate);
-    static_cast<MutableFst<Arc> *>(impl_.get())->AddArc(s, arc);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->AddArc(s, arc);
     return true;
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   int64 AddState() final {
-    return static_cast<MutableFst<Arc> *>(impl_.get())->AddState();
+    return fst::down_cast<MutableFst<Arc> *>(impl_.get())->AddState();
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   void AddStates(size_t n) final {
-    return static_cast<MutableFst<Arc> *>(impl_.get())->AddStates(n);
+    return fst::down_cast<MutableFst<Arc> *>(impl_.get())->AddStates(n);
   }
 
   const std::string &ArcType() const final { return Arc::Type(); }
 
-  FstClassImpl *Copy() final { return new FstClassImpl<Arc>(impl_.get()); }
+  FstClassImpl *Copy() final { return new FstClassImpl<Arc>(*impl_); }
 
   // Warning: calling this method casts the FST to a mutable FST.
   bool DeleteArcs(int64 s, size_t n) final {
     if (!ValidStateId(s)) return false;
-    static_cast<MutableFst<Arc> *>(impl_.get())->DeleteArcs(s, n);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->DeleteArcs(s, n);
     return true;
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   bool DeleteArcs(int64 s) final {
     if (!ValidStateId(s)) return false;
-    static_cast<MutableFst<Arc> *>(impl_.get())->DeleteArcs(s);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->DeleteArcs(s);
     return true;
   }
 
@@ -137,13 +152,13 @@ class FstClassImpl : public FstClassImplBase {
     // the underlying FST will result in truncation.
     std::vector<typename Arc::StateId> typed_dstates(dstates.size());
     std::copy(dstates.begin(), dstates.end(), typed_dstates.begin());
-    static_cast<MutableFst<Arc> *>(impl_.get())->DeleteStates(typed_dstates);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->DeleteStates(typed_dstates);
     return true;
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   void DeleteStates() final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->DeleteStates();
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->DeleteStates();
   }
 
   WeightClass Final(int64 s) const final {
@@ -160,12 +175,12 @@ class FstClassImpl : public FstClassImplBase {
 
   // Warning: calling this method casts the FST to a mutable FST.
   SymbolTable *MutableInputSymbols() final {
-    return static_cast<MutableFst<Arc> *>(impl_.get())->MutableInputSymbols();
+    return fst::down_cast<MutableFst<Arc> *>(impl_.get())->MutableInputSymbols();
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   SymbolTable *MutableOutputSymbols() final {
-    return static_cast<MutableFst<Arc> *>(impl_.get())->MutableOutputSymbols();
+    return fst::down_cast<MutableFst<Arc> *>(impl_.get())->MutableOutputSymbols();
   }
 
   // Signals failure by returning size_t max.
@@ -188,7 +203,7 @@ class FstClassImpl : public FstClassImplBase {
 
   // Warning: calling this method casts the FST to a mutable FST.
   int64 NumStates() const final {
-    return static_cast<MutableFst<Arc> *>(impl_.get())->NumStates();
+    return fst::down_cast<MutableFst<Arc> *>(impl_.get())->NumStates();
   }
 
   uint64 Properties(uint64 mask, bool test) const final {
@@ -198,13 +213,13 @@ class FstClassImpl : public FstClassImplBase {
   // Warning: calling this method casts the FST to a mutable FST.
   bool ReserveArcs(int64 s, size_t n) final {
     if (!ValidStateId(s)) return false;
-    static_cast<MutableFst<Arc> *>(impl_.get())->ReserveArcs(s, n);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->ReserveArcs(s, n);
     return true;
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   void ReserveStates(int64 n) final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->ReserveStates(n);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->ReserveStates(n);
   }
 
   const SymbolTable *OutputSymbols() const final {
@@ -213,31 +228,31 @@ class FstClassImpl : public FstClassImplBase {
 
   // Warning: calling this method casts the FST to a mutable FST.
   void SetInputSymbols(const SymbolTable *isyms) final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->SetInputSymbols(isyms);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->SetInputSymbols(isyms);
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   bool SetFinal(int64 s, const WeightClass &weight) final {
     if (!ValidStateId(s)) return false;
-    static_cast<MutableFst<Arc> *>(impl_.get())
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())
         ->SetFinal(s, *weight.GetWeight<typename Arc::Weight>());
     return true;
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   void SetOutputSymbols(const SymbolTable *osyms) final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->SetOutputSymbols(osyms);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->SetOutputSymbols(osyms);
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   void SetProperties(uint64 props, uint64 mask) final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->SetProperties(props, mask);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->SetProperties(props, mask);
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
   bool SetStart(int64 s) final {
     if (!ValidStateId(s)) return false;
-    static_cast<MutableFst<Arc> *>(impl_.get())->SetStart(s);
+    fst::down_cast<MutableFst<Arc> *>(impl_.get())->SetStart(s);
     return true;
   }
 
@@ -285,7 +300,12 @@ class FstClass : public FstClassBase {
   FstClass() : impl_(nullptr) {}
 
   template <class Arc>
-  explicit FstClass(const Fst<Arc> &fst) : impl_(new FstClassImpl<Arc>(fst)) {}
+  explicit FstClass(std::unique_ptr<Fst<Arc>> fst)
+      : impl_(fst::make_unique<FstClassImpl<Arc>>(std::move(fst))) {}
+
+  template <class Arc>
+  explicit FstClass(const Fst<Arc> &fst)
+      : impl_(fst::make_unique<FstClassImpl<Arc>>(fst)) {}
 
   FstClass(const FstClass &other)
       : impl_(other.impl_ == nullptr ? nullptr : other.impl_->Copy()) {}
@@ -372,7 +392,7 @@ class FstClass : public FstClassBase {
       return nullptr;
     } else {
       FstClassImpl<Arc> *typed_impl =
-          static_cast<FstClassImpl<Arc> *>(impl_.get());
+          fst::down_cast<FstClassImpl<Arc> *>(impl_.get());
       return typed_impl->GetImpl();
     }
   }
@@ -392,20 +412,21 @@ class FstClass : public FstClassBase {
   }
 
  protected:
-  explicit FstClass(FstClassImplBase *impl) : impl_(impl) {}
+  explicit FstClass(std::unique_ptr<FstClassImplBase> impl)
+      : impl_(std::move(impl)) {}
 
   const FstClassImplBase *GetImpl() const { return impl_.get(); }
 
   FstClassImplBase *GetImpl() { return impl_.get(); }
 
   // Generic template method for reading an arc-templated FST of type
-  // UnderlyingT, and returning it wrapped as FstClassT, with appropriat
+  // UnderlyingT, and returning it wrapped as FstClassT, with appropriate
   // error checking. Called from arc-templated Read() static methods.
   template <class FstClassT, class UnderlyingT>
   static FstClassT *ReadTypedFst(std::istream &stream,
                                  const FstReadOptions &opts) {
     std::unique_ptr<UnderlyingT> u(UnderlyingT::Read(stream, opts));
-    return u ? new FstClassT(*u) : nullptr;
+    return u ? new FstClassT(std::move(u)) : nullptr;
   }
 
  private:
@@ -471,6 +492,13 @@ class MutableFstClass : public FstClass {
   bool SetStart(int64 s) { return GetImpl()->SetStart(s); }
 
   template <class Arc>
+  explicit MutableFstClass(std::unique_ptr<MutableFst<Arc>> fst)
+      // NB: The natural cast-less way to do this doesn't compile for some
+      // arcane reason.
+      : FstClass(
+            fst::implicit_cast<std::unique_ptr<Fst<Arc>>>(std::move(fst))) {}
+
+  template <class Arc>
   explicit MutableFstClass(const MutableFst<Arc> &fst) : FstClass(fst) {}
 
   // These methods are required by IO registration.
@@ -492,7 +520,7 @@ class MutableFstClass : public FstClass {
   template <class Arc>
   MutableFst<Arc> *GetMutableFst() {
     Fst<Arc> *fst = const_cast<Fst<Arc> *>(this->GetFst<Arc>());
-    MutableFst<Arc> *mfst = static_cast<MutableFst<Arc> *>(fst);
+    MutableFst<Arc> *mfst = fst::down_cast<MutableFst<Arc> *>(fst);
     return mfst;
   }
 
@@ -504,12 +532,14 @@ class MutableFstClass : public FstClass {
   }
 
  protected:
-  explicit MutableFstClass(FstClassImplBase *impl) : FstClass(impl) {}
+  explicit MutableFstClass(std::unique_ptr<FstClassImplBase> impl)
+      : FstClass(std::move(impl)) {}
 };
 
 class VectorFstClass : public MutableFstClass {
  public:
-  explicit VectorFstClass(FstClassImplBase *impl) : MutableFstClass(impl) {}
+  explicit VectorFstClass(std::unique_ptr<FstClassImplBase> impl)
+      : MutableFstClass(std::move(impl)) {}
 
   explicit VectorFstClass(const FstClass &other);
 
@@ -525,17 +555,24 @@ class VectorFstClass : public MutableFstClass {
   }
 
   template <class Arc>
+  explicit VectorFstClass(std::unique_ptr<VectorFst<Arc>> fst)
+      // NB: The natural cast-less way to do this doesn't compile for some
+      // arcane reason.
+      : MutableFstClass(fst::implicit_cast<std::unique_ptr<MutableFst<Arc>>>(
+            std::move(fst))) {}
+
+  template <class Arc>
   explicit VectorFstClass(const VectorFst<Arc> &fst) : MutableFstClass(fst) {}
 
   template <class Arc>
   static FstClassImplBase *Convert(const FstClass &other) {
-    return new FstClassImpl<Arc>(new VectorFst<Arc>(*other.GetFst<Arc>()),
-                                 true);
+    return new FstClassImpl<Arc>(
+        fst::make_unique<VectorFst<Arc>>(*other.GetFst<Arc>()));
   }
 
   template <class Arc>
   static FstClassImplBase *Create() {
-    return new FstClassImpl<Arc>(new VectorFst<Arc>(), true);
+    return new FstClassImpl<Arc>(fst::make_unique<VectorFst<Arc>>());
   }
 };
 
index b5f5141..d5f171b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index d2ad515..eaf669d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index dcee33e..f98f0b7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 5f9c953..9b3428a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -308,6 +322,12 @@ class FstInfo {
   std::string arc_type_;
 };
 
+// Prints `properties` to `ostrm` in a user-friendly multi-line format.
+void PrintProperties(std::ostream &ostrm, uint64 properties);
+
+// Prints `header` to `ostrm` in a user-friendly multi-line format.
+void PrintHeader(std::ostream &ostrm, const FstHeader &header);
+
 }  // namespace fst
 
 #endif  // FST_SCRIPT_INFO_IMPL_H_
index df26d10..ca8f030 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index c2e311f..757d5e5 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 5bc3131..6959362 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3dba049..f217d53 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 38deed4..718a7f2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -7,6 +21,7 @@
 #include <memory>
 #include <tuple>
 
+#include <fst/types.h>
 #include <fst/arc-map.h>
 #include <fst/state-map.h>
 #include <fst/script/arg-packs.h>
@@ -17,45 +32,45 @@ namespace fst {
 namespace script {
 
 template <class M>
-Fst<typename M::ToArc> *ArcMap(const Fst<typename M::FromArc> &fst,
-                               const M &mapper) {
+std::unique_ptr<Fst<typename M::ToArc>> ArcMap(
+    const Fst<typename M::FromArc> &fst, const M &mapper) {
   using ToArc = typename M::ToArc;
-  auto *ofst = new VectorFst<ToArc>;
-  ArcMap(fst, ofst, mapper);
+  auto ofst = fst::make_unique<VectorFst<ToArc>>();
+  ArcMap(fst, ofst.get(), mapper);
   return ofst;
 }
 
 template <class M>
-Fst<typename M::ToArc> *StateMap(const Fst<typename M::FromArc> &fst,
-                                 const M &mapper) {
+std::unique_ptr<Fst<typename M::ToArc>> StateMap(
+    const Fst<typename M::FromArc> &fst, const M &mapper) {
   using ToArc = typename M::ToArc;
-  auto *ofst = new VectorFst<ToArc>;
-  StateMap(fst, ofst, mapper);
+  auto ofst = fst::make_unique<VectorFst<ToArc>>();
+  StateMap(fst, ofst.get(), mapper);
   return ofst;
 }
 
-enum MapType {
-  ARC_SUM_MAPPER,
-  ARC_UNIQUE_MAPPER,
-  IDENTITY_MAPPER,
-  INPUT_EPSILON_MAPPER,
-  INVERT_MAPPER,
-  OUTPUT_EPSILON_MAPPER,
-  PLUS_MAPPER,
-  POWER_MAPPER,
-  QUANTIZE_MAPPER,
-  RMWEIGHT_MAPPER,
-  SUPERFINAL_MAPPER,
-  TIMES_MAPPER,
-  TO_LOG_MAPPER,
-  TO_LOG64_MAPPER,
-  TO_STD_MAPPER
+enum class MapType : uint8 {
+  ARC_SUM,
+  ARC_UNIQUE,
+  IDENTITY,
+  INPUT_EPSILON,
+  INVERT,
+  OUTPUT_EPSILON,
+  PLUS,
+  POWER,
+  QUANTIZE,
+  RMWEIGHT,
+  SUPERFINAL,
+  TIMES,
+  TO_LOG,
+  TO_LOG64,
+  TO_STD
 };
 
 using MapInnerArgs =
     std::tuple<const FstClass &, MapType, float, double, const WeightClass &>;
 
-using MapArgs = WithReturnValue<FstClass *, MapInnerArgs>;
+using MapArgs = WithReturnValue<std::unique_ptr<FstClass>, MapInnerArgs>;
 
 template <class Arc>
 void Map(MapArgs *args) {
@@ -63,94 +78,91 @@ void Map(MapArgs *args) {
   const Fst<Arc> &ifst = *std::get<0>(args->args).GetFst<Arc>();
   const auto map_type = std::get<1>(args->args);
   switch (map_type) {
-    case ARC_SUM_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(StateMap(ifst, ArcSumMapper<Arc>(ifst)));
-      args->retval = new FstClass(*ofst);
+    case MapType::ARC_SUM: {
+      auto ofst = StateMap(ifst, ArcSumMapper<Arc>(ifst));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case ARC_UNIQUE_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(
-          StateMap(ifst, ArcUniqueMapper<Arc>(ifst)));
-      args->retval = new FstClass(*ofst);
+    case MapType::ARC_UNIQUE: {
+      auto ofst = StateMap(ifst, ArcUniqueMapper<Arc>(ifst));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case IDENTITY_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, IdentityArcMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::IDENTITY: {
+      auto ofst = ArcMap(ifst, IdentityArcMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case INPUT_EPSILON_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, InputEpsilonMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::INPUT_EPSILON: {
+      auto ofst = ArcMap(ifst, InputEpsilonMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case INVERT_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, InvertWeightMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::INVERT: {
+      auto ofst = ArcMap(ifst, InvertWeightMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case OUTPUT_EPSILON_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, OutputEpsilonMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::OUTPUT_EPSILON: {
+      auto ofst = ArcMap(ifst, OutputEpsilonMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case PLUS_MAPPER: {
+    case MapType::PLUS: {
       const auto weight = *std::get<4>(args->args).GetWeight<Weight>();
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, PlusMapper<Arc>(weight)));
-      args->retval = new FstClass(*ofst);
+      auto ofst = ArcMap(ifst, PlusMapper<Arc>(weight));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case POWER_MAPPER: {
+    case MapType::POWER: {
       const auto power = std::get<3>(args->args);
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, PowerMapper<Arc>(power)));
-      args->retval = new FstClass(*ofst);
+      auto ofst = ArcMap(ifst, PowerMapper<Arc>(power));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case QUANTIZE_MAPPER: {
+    case MapType::QUANTIZE: {
       const auto delta = std::get<2>(args->args);
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, QuantizeMapper<Arc>(delta)));
-      args->retval = new FstClass(*ofst);
+      auto ofst = ArcMap(ifst, QuantizeMapper<Arc>(delta));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case RMWEIGHT_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, RmWeightMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::RMWEIGHT: {
+      auto ofst = ArcMap(ifst, RmWeightMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case SUPERFINAL_MAPPER: {
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, SuperFinalMapper<Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::SUPERFINAL: {
+      auto ofst = ArcMap(ifst, SuperFinalMapper<Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case TIMES_MAPPER: {
+    case MapType::TIMES: {
       const auto weight = *std::get<4>(args->args).GetWeight<Weight>();
-      std::unique_ptr<Fst<Arc>> ofst(ArcMap(ifst, TimesMapper<Arc>(weight)));
-      args->retval = new FstClass(*ofst);
+      auto ofst = ArcMap(ifst, TimesMapper<Arc>(weight));
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case TO_LOG_MAPPER: {
-      std::unique_ptr<Fst<LogArc>> ofst(
-          ArcMap(ifst, WeightConvertMapper<Arc, LogArc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::TO_LOG: {
+      auto ofst = ArcMap(ifst, WeightConvertMapper<Arc, LogArc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case TO_LOG64_MAPPER: {
-      std::unique_ptr<Fst<Log64Arc>> ofst(
-          ArcMap(ifst, WeightConvertMapper<Arc, Log64Arc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::TO_LOG64: {
+      auto ofst = ArcMap(ifst, WeightConvertMapper<Arc, Log64Arc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
-    case TO_STD_MAPPER: {
-      std::unique_ptr<Fst<StdArc>> ofst(
-          ArcMap(ifst, WeightConvertMapper<Arc, StdArc>()));
-      args->retval = new FstClass(*ofst);
+    case MapType::TO_STD: {
+      auto ofst = ArcMap(ifst, WeightConvertMapper<Arc, StdArc>());
+      args->retval = fst::make_unique<FstClass>(std::move(ofst));
       return;
     }
   }
 }
 
-FstClass *Map(const FstClass &ifst, MapType map_type, float delta, double power,
-              const WeightClass &weight);
+std::unique_ptr<FstClass> Map(const FstClass &ifst, MapType map_type,
+                              float delta, double power,
+                              const WeightClass &weight);
 
 }  // namespace script
 }  // namespace fst
index 9445a17..626ccff 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 90594eb..c8d1d84 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index bb043dc..7c71379 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -29,21 +43,6 @@ struct PrintArgs {
   const std::string &dest;
   const std::string &sep;
   const std::string &missing_symbol;
-
-  PrintArgs(const FstClass &fst, const SymbolTable *isyms,
-            const SymbolTable *osyms, const SymbolTable *ssyms, bool accept,
-            bool show_weight_one, std::ostream &ostrm, const std::string &dest,
-            const std::string &sep, const std::string &missing_sym = "")
-      : fst(fst),
-        isyms(isyms),
-        osyms(osyms),
-        ssyms(ssyms),
-        accept(accept),
-        show_weight_one(show_weight_one),
-        ostrm(ostrm),
-        dest(dest),
-        sep(sep),
-        missing_symbol(missing_sym) {}
 };
 
 template <class Arc>
index 13edeb1..4ca6123 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a9587d8..859a6e7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3138b28..8d87e08 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index d11b121..2090cf3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -30,21 +44,21 @@ void RandEquivalent(RandEquivalentArgs *args) {
   const float delta = std::get<4>(args->args);
   const uint64 seed = std::get<5>(args->args);
   switch (opts.selector) {
-    case UNIFORM_ARC_SELECTOR: {
+    case RandArcSelection::UNIFORM: {
       const UniformArcSelector<Arc> selector(seed);
       const RandGenOptions<UniformArcSelector<Arc>> ropts(selector,
                                                           opts.max_length);
       args->retval = RandEquivalent(fst1, fst2, npath, ropts, delta, seed);
       return;
     }
-    case FAST_LOG_PROB_ARC_SELECTOR: {
+    case RandArcSelection::FAST_LOG_PROB: {
       const FastLogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<FastLogProbArcSelector<Arc>> ropts(selector,
                                                               opts.max_length);
       args->retval = RandEquivalent(fst1, fst2, npath, ropts, delta, seed);
       return;
     }
-    case LOG_PROB_ARC_SELECTOR: {
+    case RandArcSelection::LOG_PROB: {
       const LogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<LogProbArcSelector<Arc>> ropts(selector,
                                                           opts.max_length);
@@ -54,10 +68,11 @@ void RandEquivalent(RandEquivalentArgs *args) {
   }
 }
 
-bool RandEquivalent(const FstClass &fst1, const FstClass &fst2, int32 npath = 1,
-                    const RandGenOptions<RandArcSelection> &opts =
-                        RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR),
-                    float delta = kDelta, uint64 seed = std::random_device()());
+bool RandEquivalent(
+    const FstClass &fst1, const FstClass &fst2, int32 npath = 1,
+    const RandGenOptions<RandArcSelection> &opts =
+        RandGenOptions<RandArcSelection>(RandArcSelection::UNIFORM),
+    float delta = kDelta, uint64 seed = std::random_device()());
 
 }  // namespace script
 }  // namespace fst
index 3eb9734..91696ce 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -26,7 +40,7 @@ void RandGen(RandGenArgs *args) {
   const auto &opts = std::get<2>(*args);
   const uint64 seed = std::get<3>(*args);
   switch (opts.selector) {
-    case UNIFORM_ARC_SELECTOR: {
+    case RandArcSelection::UNIFORM: {
       const UniformArcSelector<Arc> selector(seed);
       const RandGenOptions<UniformArcSelector<Arc>> ropts(
           selector, opts.max_length, opts.npath, opts.weighted,
@@ -34,7 +48,7 @@ void RandGen(RandGenArgs *args) {
       RandGen(ifst, ofst, ropts);
       return;
     }
-    case FAST_LOG_PROB_ARC_SELECTOR: {
+    case RandArcSelection::FAST_LOG_PROB: {
       const FastLogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<FastLogProbArcSelector<Arc>> ropts(
           selector, opts.max_length, opts.npath, opts.weighted,
@@ -42,7 +56,7 @@ void RandGen(RandGenArgs *args) {
       RandGen(ifst, ofst, ropts);
       return;
     }
-    case LOG_PROB_ARC_SELECTOR: {
+    case RandArcSelection::LOG_PROB: {
       const LogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<LogProbArcSelector<Arc>> ropts(
           selector, opts.max_length, opts.npath, opts.weighted,
@@ -55,7 +69,7 @@ void RandGen(RandGenArgs *args) {
 
 void RandGen(const FstClass &ifst, MutableFstClass *ofst,
              const RandGenOptions<RandArcSelection> &opts =
-                 RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR),
+                 RandGenOptions<RandArcSelection>(RandArcSelection::UNIFORM),
              uint64 seed = std::random_device()());
 
 }  // namespace script
index 0232e20..3ac2220 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 1276abf..68b3494 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 295e2a6..ff255d3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3893ad8..04cb07e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 724ff8b..08da62d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -25,7 +39,7 @@ struct RmEpsilonOptions : public ShortestDistanceOptions {
   RmEpsilonOptions(QueueType queue_type, bool connect,
                    const WeightClass &weight_threshold,
                    int64 state_threshold = kNoStateId, float delta = kDelta)
-      : ShortestDistanceOptions(queue_type, EPSILON_ARC_FILTER, kNoStateId,
+      : ShortestDistanceOptions(queue_type, ArcFilterType::EPSILON, kNoStateId,
                                 delta),
         connect(connect),
         weight_threshold(weight_threshold),
@@ -69,8 +83,14 @@ void RmEpsilon(MutableFst<Arc> *fst, const RmEpsilonOptions &opts) {
       return;
     }
     case SHORTEST_FIRST_QUEUE: {
-      NaturalShortestFirstQueue<StateId, Weight> queue(distance);
-      RmEpsilon(fst, &distance, opts, &queue);
+      if constexpr (IsIdempotent<Weight>::value) {
+        NaturalShortestFirstQueue<StateId, Weight> queue(distance);
+        RmEpsilon(fst, &distance, opts, &queue);
+      } else {
+        FSTERROR() << "RmEpsilon: Bad queue type SHORTEST_FIRST_QUEUE for"
+                   << " non-idempotent Weight " << Weight::Type();
+        fst->SetProperties(kError, kError);
+      }
       return;
     }
     case STATE_ORDER_QUEUE: {
index dfd9f6d..6164a8f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
 // This file contains general-purpose templates which are used in the
 // implementation of the operations.
 
+#include <memory>
 #include <string>
 #include <utility>
+#include <vector>
 
 #include <fst/types.h>
 #include <fst/log.h>
 namespace fst {
 namespace script {
 
-enum RandArcSelection {
-  UNIFORM_ARC_SELECTOR,
-  LOG_PROB_ARC_SELECTOR,
-  FAST_LOG_PROB_ARC_SELECTOR
-};
+enum class RandArcSelection : uint8 { UNIFORM, LOG_PROB, FAST_LOG_PROB };
 
 // A generic register for operations with various kinds of signatures.
 // Needed since every function signature requires a new registration class.
@@ -207,6 +219,19 @@ void CopyWeights(const std::vector<Weight> &typed_weights,
 }
 
 }  // namespace internal
+
+// Used for Replace operations.
+inline std::vector<std::pair<int64, const FstClass *>> BorrowPairs(
+    const std::vector<std::pair<int64, std::unique_ptr<const FstClass>>>
+        &pairs) {
+  std::vector<std::pair<int64, const FstClass *>> borrowed_pairs;
+  borrowed_pairs.reserve(pairs.size());
+  for (const auto &pair : pairs) {
+    borrowed_pairs.emplace_back(pair.first, pair.second.get());
+  }
+  return borrowed_pairs;
+}
+
 }  // namespace script
 }  // namespace fst
 
index da2f45f..880333f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -7,6 +21,7 @@
 #include <tuple>
 #include <vector>
 
+#include <fst/types.h>
 #include <fst/queue.h>
 #include <fst/shortest-distance.h>
 #include <fst/script/arg-packs.h>
 namespace fst {
 namespace script {
 
-enum ArcFilterType {
-  ANY_ARC_FILTER,
-  EPSILON_ARC_FILTER,
-  INPUT_EPSILON_ARC_FILTER,
-  OUTPUT_EPSILON_ARC_FILTER
+enum class ArcFilterType : uint8 {
+  ANY,
+  EPSILON,
+  INPUT_EPSILON,
+  OUTPUT_EPSILON
 };
 
 struct ShortestDistanceOptions {
@@ -106,27 +121,28 @@ void ShortestDistance(const Fst<Arc> &fst,
                       std::vector<typename Arc::Weight> *distance,
                       const ShortestDistanceOptions &opts) {
   switch (opts.arc_filter_type) {
-    case ANY_ARC_FILTER: {
+    case ArcFilterType::ANY: {
       ShortestDistance<Arc, Queue, AnyArcFilter<Arc>>(fst, distance, opts);
       return;
     }
-    case EPSILON_ARC_FILTER: {
+    case ArcFilterType::EPSILON: {
       ShortestDistance<Arc, Queue, EpsilonArcFilter<Arc>>(fst, distance, opts);
       return;
     }
-    case INPUT_EPSILON_ARC_FILTER: {
+    case ArcFilterType::INPUT_EPSILON: {
       ShortestDistance<Arc, Queue, InputEpsilonArcFilter<Arc>>(fst, distance,
                                                                opts);
       return;
     }
-    case OUTPUT_EPSILON_ARC_FILTER: {
+    case ArcFilterType::OUTPUT_EPSILON: {
       ShortestDistance<Arc, Queue, OutputEpsilonArcFilter<Arc>>(fst, distance,
                                                                 opts);
       return;
     }
     default: {
       FSTERROR() << "ShortestDistance: Unknown arc filter type: "
-                 << opts.arc_filter_type;
+                 << static_cast<std::underlying_type<ArcFilterType>::type>(
+                        opts.arc_filter_type);
       distance->clear();
       distance->resize(1, Arc::Weight::NoWeight());
       return;
@@ -164,9 +180,14 @@ void ShortestDistance(ShortestDistanceArgs1 *args) {
       break;
     }
     case SHORTEST_FIRST_QUEUE: {
-      internal::ShortestDistance<Arc,
-                                 NaturalShortestFirstQueue<StateId, Weight>>(
-          fst, &typed_distance, opts);
+      if constexpr (IsIdempotent<Weight>::value) {
+        internal::ShortestDistance<Arc,
+                                   NaturalShortestFirstQueue<StateId, Weight>>(
+            fst, &typed_distance, opts);
+      } else {
+        FSTERROR() << "ShortestDistance: Bad queue type SHORTEST_FIRST_QUEUE"
+                   << " for non-idempotent Weight " << Weight::Type();
+      }
       break;
     }
     case STATE_ORDER_QUEUE: {
index 002052c..18f2bea 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -27,7 +41,8 @@ struct ShortestPathOptions : public ShortestDistanceOptions {
   ShortestPathOptions(QueueType queue_type, int32 nshortest, bool unique,
                       float delta, const WeightClass &weight_threshold,
                       int64 state_threshold = kNoStateId)
-      : ShortestDistanceOptions(queue_type, ANY_ARC_FILTER, kNoStateId, delta),
+      : ShortestDistanceOptions(queue_type, ArcFilterType::ANY, kNoStateId,
+                                delta),
         nshortest(nshortest),
         unique(unique),
         weight_threshold(weight_threshold),
@@ -73,8 +88,14 @@ void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
       return;
     }
     case SHORTEST_FIRST_QUEUE: {
-      ShortestPath<Arc, NaturalShortestFirstQueue<StateId, Weight>>(
-          ifst, ofst, &distance, opts);
+      if constexpr (IsIdempotent<Weight>::value) {
+        ShortestPath<Arc, NaturalShortestFirstQueue<StateId, Weight>>(
+            ifst, ofst, &distance, opts);
+      } else {
+        FSTERROR() << "ShortestPath: Bad queue type SHORTEST_FIRST_QUEUE for"
+                   << " non-idempotent Weight " << Weight::Type();
+        ofst->SetProperties(kError, kError);
+      }
       return;
     }
     case STATE_ORDER_QUEUE: {
index 6c7f8e4..1cf596d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 702ed5b..93a29d2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 99b6dd3..b98e9ae 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index fb6738d..f0167f9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 0337da7..c3a0917 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 53f4852..63743f9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 8ecdcfe..ec5d64b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -57,7 +71,7 @@ class WeightClassImpl : public WeightImplBase {
   bool Member() const final { return weight_.Member(); }
 
   bool operator==(const WeightImplBase &other) const final {
-    const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
+    const auto *typed_other = fst::down_cast<const WeightClassImpl<W> *>(&other);
     return weight_ == typed_other->weight_;
   }
 
@@ -66,19 +80,19 @@ class WeightClassImpl : public WeightImplBase {
   }
 
   WeightClassImpl<W> &PlusEq(const WeightImplBase &other) final {
-    const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
+    const auto *typed_other = fst::down_cast<const WeightClassImpl<W> *>(&other);
     weight_ = Plus(weight_, typed_other->weight_);
     return *this;
   }
 
   WeightClassImpl<W> &TimesEq(const WeightImplBase &other) final {
-    const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
+    const auto *typed_other = fst::down_cast<const WeightClassImpl<W> *>(&other);
     weight_ = Times(weight_, typed_other->weight_);
     return *this;
   }
 
   WeightClassImpl<W> &DivideEq(const WeightImplBase &other) final {
-    const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
+    const auto *typed_other = fst::down_cast<const WeightClassImpl<W> *>(&other);
     weight_ = Divide(weight_, typed_other->weight_);
     return *this;
   }
index dcf958a..3713bcc 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -31,7 +45,7 @@ constexpr char kSetSeparator = '_';  // Label separator in sets.
 // as (+, *) for the semiring. SET_INTERSECT_UNION_RESTRICTED is a
 // restricted version of (intersect, union) that requires summed
 // arguments to be equal (or an error is signalled), useful for
-// algorithms that require a unique labelled path weight.  SET_BOOLEAN
+// algorithms that require a unique labelled path weight. SET_BOOLEAN
 // treats all non-Zero() elements as equivalent (with Zero() ==
 // UnivSet()), useful for algorithms that don't really depend on the
 // detailed sets.
index fa7b594..61ba91d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index a7ebd4c..a9a57f8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index ed0f585..45f106a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -33,6 +47,10 @@ class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
 
   SignedLogWeightTpl() noexcept : PairWeight<W1, W2>() {}
 
+  // Conversion from plain LogWeightTpl.
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  SignedLogWeightTpl(const W2 &w2) : PairWeight<W1, W2>(W1(1.0), w2) {}
+
   explicit SignedLogWeightTpl(const PairWeight<W1, W2> &weight)
       : PairWeight<W1, W2>(weight) {}
 
@@ -205,6 +223,96 @@ inline bool operator!=(const SignedLogWeightTpl<T> &w1,
   return !(w1 == w2);
 }
 
+// All functions and operators with a LogWeightTpl arg need to be
+// explicitly specified since the implicit constructor will not be
+// tried in conjunction with function overloading.
+
+template <class T>
+inline SignedLogWeightTpl<T> Plus(const LogWeightTpl<T> &w1,
+                                  const SignedLogWeightTpl<T> &w2) {
+  return Plus(SignedLogWeightTpl<T>(w1), w2);
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Plus(const SignedLogWeightTpl<T> &w1,
+                                  const LogWeightTpl<T> &w2) {
+  return Plus(w1, SignedLogWeightTpl<T>(w2));
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Minus(const LogWeightTpl<T> &w1,
+                                   const SignedLogWeightTpl<T> &w2) {
+  return Minus(SignedLogWeightTpl<T>(w1), w2);
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Minus(const SignedLogWeightTpl<T> &w1,
+                                   const LogWeightTpl<T> &w2) {
+  return Minus(w1, SignedLogWeightTpl<T>(w2));
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Times(const LogWeightTpl<T> &w1,
+                                   const SignedLogWeightTpl<T> &w2) {
+  return Times(SignedLogWeightTpl<T>(w1), w2);
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Times(const SignedLogWeightTpl<T> &w1,
+                                   const LogWeightTpl<T> &w2) {
+  return Times(w1, SignedLogWeightTpl<T>(w2));
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Divide(const LogWeightTpl<T> &w1,
+                                    const SignedLogWeightTpl<T> &w2,
+                                    DivideType typ = DIVIDE_ANY) {
+  return Divide(SignedLogWeightTpl<T>(w1), w2, typ);
+}
+
+template <class T>
+inline SignedLogWeightTpl<T> Divide(const SignedLogWeightTpl<T> &w1,
+                                    const LogWeightTpl<T> &w2,
+                                    DivideType typ = DIVIDE_ANY) {
+  return Divide(w1, SignedLogWeightTpl<T>(w2), typ);
+}
+
+template <class T>
+inline bool ApproxEqual(const LogWeightTpl<T> &w1,
+                        const SignedLogWeightTpl<T> &w2, float delta = kDelta) {
+  return ApproxEqual(LogWeightTpl<T>(w1), w2, delta);
+}
+
+template <class T>
+inline bool ApproxEqual(const SignedLogWeightTpl<T> &w1,
+                        const LogWeightTpl<T> &w2, float delta = kDelta) {
+  return ApproxEqual(w1, LogWeightTpl<T>(w2), delta);
+}
+
+template <class T>
+inline bool operator==(const LogWeightTpl<T> &w1,
+                       const SignedLogWeightTpl<T> &w2) {
+  return SignedLogWeightTpl<T>(w1) == w2;
+}
+
+template <class T>
+inline bool operator==(const SignedLogWeightTpl<T> &w1,
+                       const LogWeightTpl<T> &w2) {
+  return w1 == SignedLogWeightTpl<T>(w2);
+}
+
+template <class T>
+inline bool operator!=(const LogWeightTpl<T> &w1,
+                       const SignedLogWeightTpl<T> &w2) {
+  return SignedLogWeightTpl<T>(w1) != w2;
+}
+
+template <class T>
+inline bool operator!=(const SignedLogWeightTpl<T> &w1,
+                       const LogWeightTpl<T> &w2) {
+  return w1 != SignedLogWeightTpl<T>(w2);
+}
+
 // Single-precision signed-log weight.
 using SignedLogWeight = SignedLogWeightTpl<float>;
 
index a70bd78..3b698e9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -108,6 +122,15 @@ inline SparsePowerWeight<W, K> Plus(const SparsePowerWeight<W, K> &w1,
   });
 }
 
+// Semimodule minus operation.
+template <class W, class K>
+inline SparsePowerWeight<W, K> Minus(const SparsePowerWeight<W, K> &w1,
+                                     const SparsePowerWeight<W, K> &w2) {
+  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
+    return Minus(v1, v2);
+  });
+}
+
 // Semimodule times operation.
 template <class W, class K>
 inline SparsePowerWeight<W, K> Times(const SparsePowerWeight<W, K> &w1,
index 68c9c66..be5d3fb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e9dc20a..3d67854 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -9,6 +23,7 @@
 #define FST_STATE_MAP_H_
 
 #include <algorithm>
+#include <memory>
 #include <string>
 #include <utility>
 
@@ -162,8 +177,8 @@ class StateMapStateIteratorBase : public StateIteratorBase<B> {
   using Arc = B;
   using StateId = typename Arc::StateId;
 
-  explicit StateMapStateIteratorBase(StateIteratorBase<A> *base)
-      : base_(base) {}
+  explicit StateMapStateIteratorBase(std::unique_ptr<StateIteratorBase<A>> base)
+      : base_(std::move(base)) {}
 
   bool Done() const final { return base_->Done(); }
 
@@ -261,8 +276,9 @@ class StateMapFstImpl : public CacheImpl<B> {
   void InitStateIterator(StateIteratorData<B> *datb) const {
     StateIteratorData<A> data;
     fst_->InitStateIterator(&data);
-    datb->base =
-        data.base ? new StateMapStateIteratorBase<A, B>(data.base) : nullptr;
+    datb->base = data.base ? fst::make_unique<StateMapStateIteratorBase<A, B>>(
+                                 std::move(data.base))
+                           : nullptr;
     datb->nstates = data.nstates;
   }
 
index 36b5559..98082f8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 2777b3d..130ce8a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 87c72ae..c70d73e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -60,7 +74,7 @@ void StateSort(MutableFst<Arc> *fst,
       }
       fst->SetFinal(s2, final1);
       fst->DeleteArcs(s2);
-      for (auto arc : arcsa) {  // Copy intended.
+      for (auto arc : arcsa) {  // NOLINT(performance-for-range-copy)
         arc.nextstate = order[arc.nextstate];
         fst->AddArc(s2, arc);
       }
index 29f5e40..8b86855 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -24,7 +38,7 @@ constexpr int kStringInfinity = -1;     // Label for the infinite string.
 constexpr int kStringBad = -2;          // Label for a non-string.
 constexpr char kStringSeparator = '_';  // Label separator in strings.
 
-// Determines whether to use left or right string semiring.  Includes a
+// Determines whether to use left or right string semiring. Includes a
 // 'restricted' version that signals an error if proper prefixes/suffixes
 // would otherwise be returned by Plus, useful with various
 // algorithms that require functional transducer input with the
@@ -469,7 +483,7 @@ inline StringWeight<Label, STRING_LEFT> Divide(
     const StringWeight<Label, STRING_LEFT> &w2, DivideType divide_type) {
   if (divide_type != DIVIDE_LEFT) {
     FSTERROR() << "StringWeight::Divide: Only left division is defined "
-               << "for the left std::string semiring";
+               << "for the left string semiring";
     return StringWeight<Label, STRING_LEFT>::NoWeight();
   }
   return DivideLeft(w1, w2);
@@ -482,7 +496,7 @@ inline StringWeight<Label, STRING_RIGHT> Divide(
     const StringWeight<Label, STRING_RIGHT> &w2, DivideType divide_type) {
   if (divide_type != DIVIDE_RIGHT) {
     FSTERROR() << "StringWeight::Divide: Only right division is defined "
-               << "for the right std::string semiring";
+               << "for the right string semiring";
     return StringWeight<Label, STRING_RIGHT>::NoWeight();
   }
   return DivideRight(w1, w2);
@@ -717,7 +731,8 @@ struct GallicWeight<Label, W, GALLIC>
   GallicWeight() {}
 
   // Copy constructor.
-  GallicWeight(const UW &weight) : UW(weight) {}  // NOLINT
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  GallicWeight(const UW &weight) : UW(weight) {}
 
   // Singleton constructors: create a GALLIC weight containing a single
   // GALLIC_RESTRICT weight. Takes as argument (1) a GALLIC_RESTRICT weight or
index a2f6f21..54f3d4f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 34296fb..be59f46 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -16,7 +30,7 @@
 namespace fst {
 
 // Returns a minimal symbol table containing only symbols referenced by the
-// passed fst.  Symbols preserve their original numbering, so fst does not
+// passed fst. Symbols preserve their original numbering, so fst does not
 // require relabeling.
 template <class Arc>
 SymbolTable *PruneSymbolTable(const Fst<Arc> &fst, const SymbolTable &syms,
index 8de7f08..a34acee 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -48,17 +62,18 @@ constexpr int64 kNoSymbol = -1;
 
 class SymbolTable;
 
-// WARNING: Reading via symbol table read options should
-//          not be used. This is a temporary work around for
-//          reading symbol ranges of previously stored symbol sets.
-struct SymbolTableReadOptions {
+struct OPENFST_DEPRECATED(
+    "Reading via SymbolTableReadOptions is deprecated. Please directly provide "
+    "source string instead.") SymbolTableReadOptions {
   SymbolTableReadOptions() {}
 
   SymbolTableReadOptions(
+      OPENFST_DEPRECATED("Do not use `string_hash_ranges`; it is ignored.")
       std::vector<std::pair<int64, int64>> string_hash_ranges,
       const std::string &source)
       : string_hash_ranges(std::move(string_hash_ranges)), source(source) {}
 
+  OPENFST_DEPRECATED("Do not use `string_hash_ranges`; it is ignored.")
   std::vector<std::pair<int64, int64>> string_hash_ranges;
   std::string source;
 };
@@ -137,9 +152,14 @@ class SymbolTableImplBase {
   virtual int64 AddSymbol(SymbolType symbol, int64 key) = 0;
   virtual int64 AddSymbol(SymbolType symbol) = 0;
 
+  // Removes the symbol with the specified key. Subsequent Find() calls
+  // for this key will return the empty string. Does not affect the keys
+  // of other symbols.
   virtual void RemoveSymbol(int64 key) = 0;
 
+  // Returns the symbol for the specified key, or the empty string if not found.
   virtual std::string Find(int64 key) const = 0;
+  // Returns the key for the specified symbol, or kNoSymbol if not found.
   virtual int64 Find(SymbolType symbol) const = 0;
 
   virtual bool Member(int64 key) const { return !Find(key).empty(); }
@@ -205,7 +225,7 @@ class SymbolTableImpl final : public MutableSymbolTableImpl {
         check_sum_finalized_(false) {}
 
   std::unique_ptr<SymbolTableImplBase> Copy() const override {
-    return std::unique_ptr<SymbolTableImplBase>(new SymbolTableImpl(*this));
+    return fst::make_unique<SymbolTableImpl>(*this);
   }
 
   int64 AddSymbol(SymbolType symbol, int64 key) override;
@@ -386,9 +406,9 @@ class SymbolTable {
   static SymbolTable *ReadText(
       std::istream &strm, const std::string &name,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
-    std::shared_ptr<internal::SymbolTableImpl> impl(
-        internal::SymbolTableImpl::ReadText(strm, name, opts));
-    return impl ? new SymbolTable(impl) : nullptr;
+    auto impl =
+        fst::WrapUnique(internal::SymbolTableImpl::ReadText(strm, name, opts));
+    return impl ? new SymbolTable(std::move(impl)) : nullptr;
   }
 
   // Reads a text representation of the symbol table.
@@ -396,13 +416,11 @@ class SymbolTable {
       const std::string &source,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions());
 
-  // WARNING: Reading via symbol table read options should not be used. This is
-  // a temporary work-around.
+  OPENFST_DEPRECATED("Use `Read(std::istream&, const std::string&)` instead.")
   static SymbolTable *Read(std::istream &strm,
                            const SymbolTableReadOptions &opts) {
-    std::shared_ptr<internal::SymbolTableImpl> impl(
-        internal::SymbolTableImpl::Read(strm, opts));
-    return impl ? new SymbolTable(impl) : nullptr;
+    auto impl = fst::WrapUnique(internal::SymbolTableImpl::Read(strm, opts));
+    return impl ? new SymbolTable(std::move(impl)) : nullptr;
   }
 
   // Reads a binary dump of the symbol table from a stream.
@@ -454,7 +472,8 @@ class SymbolTable {
   int64 AvailableKey() const { return impl_->AvailableKey(); }
 
   // Return the label-agnostic MD5 check-sum for this table. All new symbols
-  // added to the table will result in an updated checksum. Deprecated.
+  // added to the table will result in an updated checksum.
+  OPENFST_DEPRECATED("Use `LabeledCheckSum()` instead.")
   const std::string &CheckSum() const { return impl_->CheckSum(); }
 
   int64 GetNthKey(ssize_t pos) const { return impl_->GetNthKey(pos); }
@@ -515,17 +534,17 @@ class SymbolTable {
 
  protected:
   explicit SymbolTable(std::shared_ptr<internal::SymbolTableImplBase> impl)
-      : impl_(impl) {}
+      : impl_(std::move(impl)) {}
 
   template <class T = internal::SymbolTableImplBase>
   const T *Impl() const {
-    return static_cast<const T *>(impl_.get());
+    return fst::down_cast<const T *>(impl_.get());
   }
 
   template <class T = internal::SymbolTableImplBase>
   T *MutableImpl() {
     MutateCheck();
-    return static_cast<T *>(impl_.get());
+    return fst::down_cast<T *>(impl_.get());
   }
 
  private:
index 8f77b96..3565409 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -380,7 +394,7 @@ class ArcIterator<SynchronizeFst<Arc>>
 template <class Arc>
 inline void SynchronizeFst<Arc>::InitStateIterator(
     StateIteratorData<Arc> *data) const {
-  data->base = new StateIterator<SynchronizeFst<Arc>>(*this);
+  data->base = fst::make_unique<StateIterator<SynchronizeFst<Arc>>>(*this);
 }
 
 // Synchronizes a transducer. This version writes the synchronized result to a
index b0ea483..907a7e3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index bf663f7..41e39e3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 1c0546d..2bc8d41 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #ifndef FST_TEST_COMPACTORS_H_
 #define FST_TEST_COMPACTORS_H_
 
@@ -67,7 +81,8 @@ class TrivialCompactor {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  TrivialCompactor() { CHECK(false); }
+  // Any empty FST is OK.
+  TrivialCompactor() : fst_(new VectorFst<Arc>) {}
 
   // Constructor from the Fst to be compacted.  If compactor is present,
   // only optional state should be copied from it.
index 6184c4c..aa6ffb3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -209,7 +223,7 @@ class FstTester {
       // generic read/cast/test
       Fst<Arc> *gfst = Fst<Arc>::Read(filename);
       CHECK(gfst);
-      G *dfst = static_cast<G *>(gfst);
+      G *dfst = fst::down_cast<G *>(gfst);
       TestBase(*dfst);
 
       // generic write/read/test
index 34553a9..ff5dd4a 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #ifndef FST_TEST_RAND_FST_H_
 #define FST_TEST_RAND_FST_H_
 
index ff5bead..9255dc0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -23,7 +37,7 @@ class WeightTester {
   explicit WeightTester(WeightGenerator generator)
       : weight_generator_(std::move(generator)) {}
 
-  void Test(int iterations, bool test_division = true) {
+  void Test(int iterations) {
     for (int i = 0; i < iterations; ++i) {
       // Selects the test weights.
       const Weight w1(weight_generator_());
@@ -36,7 +50,7 @@ class WeightTester {
       VLOG(1) << "w3 = " << w3;
 
       TestSemiring(w1, w2, w3);
-      if (test_division) TestDivision(w1, w2);
+      TestDivision(w1, w2);
       TestReverse(w1, w2);
       TestEquality(w1, w2, w3);
       TestIO(w1);
@@ -118,6 +132,7 @@ class WeightTester {
   // Tests division operation.
   void TestDivision(Weight w1, Weight w2) {
     Weight p = Times(w1, w2);
+    VLOG(1) << "TestDivision: p = " << p;
 
     if (Weight::Properties() & kLeftSemiring) {
       Weight d = Divide(p, w1, DIVIDE_LEFT);
@@ -134,8 +149,10 @@ class WeightTester {
     }
 
     if (Weight::Properties() & kCommutative) {
-      Weight d = Divide(p, w1, DIVIDE_RIGHT);
-      if (d.Member()) CHECK(ApproxEqual(p, Times(d, w1)));
+      Weight d1 = Divide(p, w1, DIVIDE_ANY);
+      if (d1.Member()) CHECK(ApproxEqual(p, Times(d1, w1)));
+      Weight d2 = Divide(p, w2, DIVIDE_ANY);
+      if (d2.Member()) CHECK(ApproxEqual(p, Times(w2, d2)));
     }
   }
 
index e261423..34645de 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index d0dd9e5..aafd451 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index b5c7f10..cd3f014 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 6426dcb..9724c1e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -78,8 +92,6 @@ class UnionWeight {
 
   friend class UnionWeightIterator<W, O>;
   friend class UnionWeightReverseIterator<W, O>;
-  friend bool operator==
-      <>(const UnionWeight<W, O> &, const UnionWeight<W, O> &);
 
   // Sets represented as first_ weight + rest_ weights. Uses first_ as
   // NoWeight() to indicate the union weight Zero() as the empty set. Uses
@@ -90,19 +102,20 @@ class UnionWeight {
     if (!weight.Member()) rest_.push_back(W::NoWeight());
   }
 
-  static const UnionWeight<W, O> &Zero() {
-    static const UnionWeight<W, O> zero{};
-    return zero;
+  static const UnionWeight &Zero() {
+    static const auto *const zero = new UnionWeight;
+    return *zero;
   }
 
-  static const UnionWeight<W, O> &One() {
-    static const UnionWeight<W, O> one(W::One());
-    return one;
+  static const UnionWeight &One() {
+    static const auto *const one = new UnionWeight(W::One());
+    return *one;
   }
 
-  static const UnionWeight<W, O> &NoWeight() {
-    static const UnionWeight<W, O> no_weight(W::Zero(), W::NoWeight());
-    return no_weight;
+  static const UnionWeight &NoWeight() {
+    static const auto *const no_weight =
+        new UnionWeight(W::Zero(), W::NoWeight());
+    return *no_weight;
   }
 
   static const std::string &Type() {
@@ -124,7 +137,7 @@ class UnionWeight {
 
   size_t Hash() const;
 
-  UnionWeight<W, O> Quantize(float delta = kDelta) const;
+  UnionWeight Quantize(float delta = kDelta) const;
 
   ReverseWeight Reverse() const;
 
@@ -294,7 +307,7 @@ inline bool UnionWeight<W, O>::Member() const {
 
 template <class W, class O>
 inline UnionWeight<W, O> UnionWeight<W, O>::Quantize(float delta) const {
-  UnionWeight<W, O> weight;
+  UnionWeight weight;
   for (UnionWeightIterator<W, O> it(*this); !it.Done(); it.Next()) {
     weight.PushBack(it.Value().Quantize(delta), true);
   }
index 77fb18f..1357035 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index e18fd90..ddb70e9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -57,7 +71,7 @@ inline std::istream &ReadType(std::istream &strm, T *t) {
 }
 
 // String case.
-inline std::istream &ReadType(std::istream &strm, std::string *s) {  // NOLINT
+inline std::istream &ReadType(std::istream &strm, std::string *s) {
   s->clear();
   int32 ns = 0;
   ReadType(strm, &ns);
@@ -172,8 +186,7 @@ inline std::ostream &WriteType(std::ostream &strm, const T t) {
 }
 
 // String case.
-inline std::ostream &WriteType(std::ostream &strm,  // NOLINT
-                               const std::string &s) {
+inline std::ostream &WriteType(std::ostream &strm, const std::string &s) {
   int32 ns = s.size();
   WriteType(strm, ns);
   return strm.write(s.data(), ns);
@@ -202,7 +215,7 @@ std::ostream &WriteType(std::ostream &strm, const std::unordered_set<T...> &c);
 // Pair case.
 template <typename S, typename T>
 inline std::ostream &WriteType(std::ostream &strm,
-                               const std::pair<S, T> &p) {  // NOLINT
+                               const std::pair<S, T> &p) {
   WriteType(strm, p.first);
   WriteType(strm, p.second);
   return strm;
@@ -380,10 +393,7 @@ class CompactSet {
 
   CompactSet() : min_key_(NoKey), max_key_(NoKey) {}
 
-  CompactSet(const CompactSet<Key, NoKey> &compact_set)
-      : set_(compact_set.set_),
-        min_key_(compact_set.min_key_),
-        max_key_(compact_set.max_key_) {}
+  CompactSet(const CompactSet &) = default;
 
   void Insert(Key key) {
     set_.insert(key);
index c818798..8c5e8a2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -19,7 +33,6 @@
 #include <fst/mutable-fst.h>
 #include <fst/test-properties.h>
 
-
 namespace fst {
 
 template <class A, class S>
@@ -461,7 +474,7 @@ VectorFstImpl<S>::VectorFstImpl(const Fst<Arc> &fst) {
 template <class S>
 VectorFstImpl<S> *VectorFstImpl<S>::Read(std::istream &strm,
                                          const FstReadOptions &opts) {
-  std::unique_ptr<VectorFstImpl> impl(new VectorFstImpl());
+  auto impl = fst::make_unique<VectorFstImpl>();
   FstHeader hdr;
   if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return nullptr;
   impl->BaseImpl::SetStart(hdr.Start());
@@ -802,7 +815,8 @@ class MutableArcIterator<VectorFst<Arc, State>>
 template <class Arc, class State>
 inline void VectorFst<Arc, State>::InitMutableArcIterator(
     StateId s, MutableArcIteratorData<Arc> *data) {
-  data->base = new MutableArcIterator<VectorFst<Arc, State>>(this, s);
+  data->base =
+      fst::make_unique<MutableArcIterator<VectorFst<Arc, State>>>(this, s);
 }
 
 // A useful alias when using StdArc.
index fd00677..d4a7112 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 7d0ebcd..5c1911d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 418848a..ae8f576 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -74,7 +88,7 @@ namespace fst {
 //          Divide(c, a, DIVIDE_ANY) = Divide(c, a, DIVIDE_LEFT)
 //           = Divide(c, a, DIVIDE_RIGHT)
 //        * for all a, b, b', c:
-//          if Times(a, b), Divide(c, a, DIVIDE_ANY) = b' and b'.Member(),
+//          if Times(a, b) = c, Divide(c, a, DIVIDE_ANY) = b' and b'.Member(),
 //          then Times(a, b') = c
 //     - In the case where there exist no b such that c = Times(a, b), the
 //       return value of Divide(c, a, DIVIDE_LEFT) is unspecified. Returning
@@ -100,9 +114,15 @@ namespace fst {
 //   Properties: specifies additional properties that hold:
 //      LeftSemiring: indicates weights form a left semiring.
 //      RightSemiring: indicates weights form a right semiring.
-//      Commutative: for all a,b: Times(a,b) == Times(b,a)
+//      Commutative: for all a, b: Times(a,b) == Times(b, a)
 //      Idempotent: for all a: Plus(a, a) == a.
 //      Path: for all a, b: Plus(a, b) == a or Plus(a, b) == b.
+//
+// User-defined weights and their corresponding operations SHOULD be
+// defined in the same namespace, but SHOULD NOT defined in the fst
+// namespace. Defining them in fst would make the user code fragile
+// to additions in fst. They will be found in another namespace
+// via argument-dependent lookup.
 
 // CONSTANT DEFINITIONS
 
@@ -166,39 +186,19 @@ enum DivideType {
 //
 // We define the strict version of this order below.
 
-// Declares the template with a second parameter determining whether or not it
-// can actually be constructed.
-template <class W, class IdempotentType = void>
-class NaturalLess;
-
-// Variant for idempotent weights.
+// Requires W is idempotent.
 template <class W>
-class NaturalLess<W, typename std::enable_if<IsIdempotent<W>::value>::type> {
- public:
+struct NaturalLess {
   using Weight = W;
+  static_assert(IsIdempotent<W>::value, "W must be idempotent.");
 
-  NaturalLess() {}
+  NaturalLess() = default;  // Work-around possible GCC bug
 
   bool operator()(const Weight &w1, const Weight &w2) const {
     return w1 != w2 && Plus(w1, w2) == w1;
   }
 };
 
-// Non-constructible variant for non-idempotent weights.
-template <class W>
-class NaturalLess<W, typename std::enable_if<!IsIdempotent<W>::value>::type> {
- public:
-  using Weight = W;
-
-  // TODO(kbg): Trace down anywhere this is being instantiated, then add a
-  // static_assert to prevent this from being instantiated.
-  NaturalLess() {
-    FSTERROR() << "NaturalLess: Weight type is not idempotent: " << W::Type();
-  }
-
-  bool operator()(const Weight &, const Weight &) const { return false; }
-};
-
 // Power is the iterated product for arbitrary semirings such that Power(w, 0)
 // is One() for the semiring, and Power(w, n) = Times(Power(w, n - 1), w).
 template <class Weight>
@@ -329,7 +329,7 @@ class CompositeWeightWriter : public internal::CompositeWeightIO {
 
 // Helper class for reading textual composite weights. Elements are separated by
 // a separator character. There must be at least one element per textual
-// representation.  Parentheses characters should be set if the composite
+// representation. Parentheses characters should be set if the composite
 // weights themselves contain composite weights to ensure proper parsing.
 class CompositeWeightReader : public internal::CompositeWeightIO {
  public:
index 4b222dd..95da1e7 100644 (file)
@@ -1,6 +1,21 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // Aggregator file for common things that need to be defined when building
 // for Windows.
+
 #ifdef _WIN32
 #include <basetsd.h>
 using ssize_t = SSIZE_T;
-#endif
\ No newline at end of file
+#endif
index aa0d486..ca8b662 100644 (file)
@@ -4,5 +4,5 @@ lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
-libfst_la_LDFLAGS = -version-info 22:0:0
+libfst_la_LDFLAGS = -version-info 23:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index a39a5c6..8f18f22 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -355,7 +355,7 @@ libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
 
-libfst_la_LDFLAGS = -version-info 22:0:0
+libfst_la_LDFLAGS = -version-info 23:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index fa130dd..61a4509 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 78af184..d39042d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index f9441f6..8ad9c82 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -37,24 +51,6 @@ const char arc_lookahead_fst_type[] = "arc_lookahead";
 const char ilabel_lookahead_fst_type[] = "ilabel_lookahead";
 const char olabel_lookahead_fst_type[] = "olabel_lookahead";
 
-// Identifies stream data as an FST (and its endianity).
-constexpr int32 kFstMagicNumber = 2125659606;
-
-// Checks for FST magic number in stream, to indicate caller function that the
-// stream content is an FST header.
-bool IsFstHeader(std::istream &strm, const std::string &) {
-  int64 pos = strm.tellg();
-  bool match = true;
-  int32 magic_number = 0;
-  ReadType(strm, &magic_number);
-  if (magic_number != kFstMagicNumber) {
-    LOG(WARNING) << "Magic number not matched. Got: " << magic_number;
-    match = false;
-  }
-  strm.seekg(pos);
-  return match;
-}
-
 // Checks FST magic number and reads in the header; if rewind = true,
 // the stream is repositioned before call if possible.
 bool FstHeader::Read(std::istream &strm, const std::string &source,
@@ -109,7 +105,7 @@ std::string FstHeader::DebugString() const {
   return ostrm.str();
 }
 
-FstReadOptions::FstReadOptions(const std::string &source,
+FstReadOptions::FstReadOptions(const std::string_view source,
                                const FstHeader *header,
                                const SymbolTable *isymbols,
                                const SymbolTable *osymbols)
@@ -122,7 +118,7 @@ FstReadOptions::FstReadOptions(const std::string &source,
   mode = ReadMode(FLAGS_fst_read_mode);
 }
 
-FstReadOptions::FstReadOptions(const std::string &source,
+FstReadOptions::FstReadOptions(const std::string_view source,
                                const SymbolTable *isymbols,
                                const SymbolTable *osymbols)
     : source(source),
index adaa8b3..3f692d2 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 97dcaab..e486918 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -330,9 +344,13 @@ uint64 ReverseProperties(uint64 inprops, bool has_superinitial) {
 }
 
 // Properties for re-weighted FST.
-uint64 ReweightProperties(uint64 inprops) {
+uint64 ReweightProperties(uint64 inprops, bool added_start_epsilon) {
   auto outprops = inprops & kWeightInvariantProperties;
   outprops = outprops & ~kCoAccessible;
+  if (added_start_epsilon) {
+    outprops &= ~(kNoEpsilons | kNoIEpsilons | kNoOEpsilons | kInitialCyclic);
+    outprops |= kEpsilons | kIEpsilons | kOEpsilons | kInitialAcyclic;
+  }
   return outprops;
 }
 
index 942e92b..13bf592 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 378252a..61c8ad4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -120,7 +134,7 @@ void ConstSymbolTableImpl::AddTable(const SymbolTable &table) {
 SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
                                            const std::string &source,
                                            const SymbolTableTextOptions &opts) {
-  std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(source));
+  auto impl = fst::make_unique<SymbolTableImpl>(source);
   int64 nline = 0;
   char line[kLineLen];
   const auto separator = opts.fst_field_separator + "\n";
@@ -277,7 +291,7 @@ SymbolTableImpl *SymbolTableImpl::Read(std::istream &strm,
   }
   std::string name;
   ReadType(strm, &name);
-  std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(name));
+  auto impl = fst::make_unique<SymbolTableImpl>(name);
   ReadType(strm, &impl->available_key_);
   int64 size;
   ReadType(strm, &size);
index 2eb0a41..9839501 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index b34dd0a..7d49a34 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 #include <fst/weight.h>
 
 DEFINE_string(fst_weight_separator, ",",
index 2fb2773..50a0902 100644 (file)
@@ -13,5 +13,5 @@ shortest-distance.cc shortest-path.cc stateiterator-class.cc synchronize.cc \
 text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-libfstscript_la_LDFLAGS = -version-info 22:0:0
+libfstscript_la_LDFLAGS = -version-info 23:0:0
 endif
index 5ee2db1..1f0fcb3 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_TRUE@text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 @HAVE_SCRIPT_TRUE@libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 22:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 23:0:0
 all: all-am
 
 .SUFFIXES:
index 3ccb8a3..62a71b8 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index ca359d5..4acd109 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 21022cd..7b7a271 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 56f80dd..9ada9cd 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -20,18 +34,16 @@ void CompileFst(std::istream &istrm, const std::string &source,
   fst->Write(dest);
 }
 
-FstClass *CompileFstInternal(std::istream &istrm, const std::string &source,
-                             const std::string &fst_type,
-                             const std::string &arc_type,
-                             const SymbolTable *isyms, const SymbolTable *osyms,
-                             const SymbolTable *ssyms, bool accep, bool ikeep,
-                             bool okeep, bool nkeep,
-                             bool allow_negative_labels) {
-  CompileFstInnerArgs iargs(istrm, source, fst_type, isyms, osyms, ssyms, accep,
-                            ikeep, okeep, nkeep, allow_negative_labels);
+std::unique_ptr<FstClass> CompileFstInternal(
+    std::istream &istrm, const std::string &source, const std::string &fst_type,
+    const std::string &arc_type, const SymbolTable *isyms,
+    const SymbolTable *osyms, const SymbolTable *ssyms, bool accep, bool ikeep,
+    bool okeep, bool nkeep, bool allow_negative_labels) {
+  CompileFstInnerArgs iargs{istrm, source, fst_type, isyms, osyms, ssyms, accep,
+                            ikeep, okeep, nkeep, allow_negative_labels};
   CompileFstArgs args(iargs);
   Apply<Operation<CompileFstArgs>>("CompileFstInternal", arc_type, &args);
-  return args.retval;
+  return std::move(args.retval);
 }
 
 // This registers form 2; 1 does not require registration.
index a39504c..920b39b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 3f813fa..bca10c3 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2acb4de..26dd956 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 1c31fcb..206abf9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 namespace fst {
 namespace script {
 
-FstClass *Convert(const FstClass &ifst, const std::string &new_type) {
+std::unique_ptr<FstClass> Convert(const FstClass &ifst,
+                                  const std::string &new_type) {
   ConvertInnerArgs iargs(ifst, new_type);
   ConvertArgs args(iargs);
   Apply<Operation<ConvertArgs>>("Convert", ifst.ArcType(), &args);
-  return args.retval;
+  return std::move(args.retval);
 }
 
 REGISTER_FST_OPERATION_3ARCS(Convert, ConvertArgs);
index 314f367..470ccc1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 81056de..8b8453c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 4b7efe0..f8a8568 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index a39a0de..f09ec53 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 27e6707..4591aeb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -14,9 +28,9 @@ void Draw(const FstClass &fst, const SymbolTable *isyms,
           bool vertical, float ranksep, float nodesep, int fontsize,
           int precision, const std::string &float_format, bool show_weight_one,
           std::ostream &ostrm, const std::string &dest) {
-  DrawArgs args(fst, isyms, osyms, ssyms, accep, title, width, height, portrait,
+  DrawArgs args{fst, isyms, osyms, ssyms, accep, title, width, height, portrait,
                 vertical, ranksep, nodesep, fontsize, precision, float_format,
-                show_weight_one, ostrm, dest);
+                show_weight_one, ostrm, dest};
   Apply<Operation<DrawArgs>>("Draw", fst.ArcType(), &args);
 }
 
index 37faf91..103093d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 6ecd7ee..730216e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 025a28a..b6510cf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 9868de3..45f3e33 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 376db22..ea024a1 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 2ee3b98..268e767 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -8,6 +22,7 @@
 #include <fst/script/fst-class.h>
 
 #include <istream>
+#include <memory>
 
 #include <fst/log.h>
 #include <fst/equal.h>
@@ -41,25 +56,25 @@ F *ReadFstClass(std::istream &istrm, const std::string &source) {
 }
 
 template <class F>
-FstClassImplBase *CreateFstClass(const std::string &arc_type) {
+std::unique_ptr<FstClassImplBase> CreateFstClass(const std::string &arc_type) {
   static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
   auto creator = reg->GetCreator(arc_type);
   if (!creator) {
     FSTERROR() << "CreateFstClass: Unknown arc type: " << arc_type;
     return nullptr;
   }
-  return creator();
+  return fst::WrapUnique(creator());
 }
 
 template <class F>
-FstClassImplBase *ConvertFstClass(const FstClass &other) {
+std::unique_ptr<FstClassImplBase> ConvertFstClass(const FstClass &other) {
   static const auto *reg = FstClassIORegistration<F>::Register::GetRegister();
   auto converter = reg->GetConverter(other.ArcType());
   if (!converter) {
     FSTERROR() << "ConvertFstClass: Unknown arc type: " << other.ArcType();
     return nullptr;
   }
-  return converter(other);
+  return fst::WrapUnique(converter(other));
 }
 
 }  // namespace
@@ -104,7 +119,7 @@ MutableFstClass *MutableFstClass::Read(const std::string &source,
     std::unique_ptr<FstClass> ifst(FstClass::Read(source));
     if (!ifst) return nullptr;
     if (ifst->Properties(kMutable, false) == kMutable) {
-      return static_cast<MutableFstClass *>(ifst.release());
+      return fst::down_cast<MutableFstClass *>(ifst.release());
     } else {
       return new VectorFstClass(*ifst.release());
     }
index 5c012b9..c5cff74 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -8,9 +22,9 @@ namespace script {
 
 bool GetArcSortType(const std::string &str, ArcSortType *sort_type) {
   if (str == "ilabel") {
-    *sort_type = ILABEL_SORT;
+    *sort_type = ArcSortType::ILABEL;
   } else if (str == "olabel") {
-    *sort_type = OLABEL_SORT;
+    *sort_type = ArcSortType::OLABEL;
   } else {
     return false;
   }
@@ -53,35 +67,35 @@ bool GetDeterminizeType(const std::string &str, DeterminizeType *det_type) {
 
 bool GetMapType(const std::string &str, MapType *map_type) {
   if (str == "arc_sum") {
-    *map_type = ARC_SUM_MAPPER;
+    *map_type = MapType::ARC_SUM;
   } else if (str == "arc_unique") {
-    *map_type = ARC_UNIQUE_MAPPER;
+    *map_type = MapType::ARC_UNIQUE;
   } else if (str == "identity") {
-    *map_type = IDENTITY_MAPPER;
+    *map_type = MapType::IDENTITY;
   } else if (str == "input_epsilon") {
-    *map_type = INPUT_EPSILON_MAPPER;
+    *map_type = MapType::INPUT_EPSILON;
   } else if (str == "invert") {
-    *map_type = INVERT_MAPPER;
+    *map_type = MapType::INVERT;
   } else if (str == "output_epsilon") {
-    *map_type = OUTPUT_EPSILON_MAPPER;
+    *map_type = MapType::OUTPUT_EPSILON;
   } else if (str == "plus") {
-    *map_type = PLUS_MAPPER;
+    *map_type = MapType::PLUS;
   } else if (str == "power") {
-    *map_type = POWER_MAPPER;
+    *map_type = MapType::POWER;
   } else if (str == "quantize") {
-    *map_type = QUANTIZE_MAPPER;
+    *map_type = MapType::QUANTIZE;
   } else if (str == "rmweight") {
-    *map_type = RMWEIGHT_MAPPER;
+    *map_type = MapType::RMWEIGHT;
   } else if (str == "superfinal") {
-    *map_type = SUPERFINAL_MAPPER;
+    *map_type = MapType::SUPERFINAL;
   } else if (str == "times") {
-    *map_type = TIMES_MAPPER;
+    *map_type = MapType::TIMES;
   } else if (str == "to_log") {
-    *map_type = TO_LOG_MAPPER;
+    *map_type = MapType::TO_LOG;
   } else if (str == "to_log64") {
-    *map_type = TO_LOG64_MAPPER;
+    *map_type = MapType::TO_LOG64;
   } else if (str == "to_std" || str == "to_standard") {
-    *map_type = TO_STD_MAPPER;
+    *map_type = MapType::TO_STD;
   } else {
     return false;
   }
@@ -101,11 +115,11 @@ bool GetProjectType(const std::string &str, ProjectType *project_type) {
 
 bool GetRandArcSelection(const std::string &str, RandArcSelection *ras) {
   if (str == "uniform") {
-    *ras = UNIFORM_ARC_SELECTOR;
+    *ras = RandArcSelection::UNIFORM;
   } else if (str == "log_prob") {
-    *ras = LOG_PROB_ARC_SELECTOR;
+    *ras = RandArcSelection::LOG_PROB;
   } else if (str == "fast_log_prob") {
-    *ras = FAST_LOG_PROB_ARC_SELECTOR;
+    *ras = RandArcSelection::FAST_LOG_PROB;
   } else {
     return false;
   }
index 7614cf9..c42f5a4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 
 namespace fst {
 
+// Column width for property names.
+constexpr int kWidth = 50;
+
 void FstInfo::Info() const {
   std::ostream &ostrm = std::cout;
   const auto old = ostrm.setf(std::ios::left);
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "fst type" << FstType() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "arc type" << ArcType() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "input symbol table" << InputSymbols() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "output symbol table" << OutputSymbols() << std::endl;
   if (!LongInfo()) {
     ostrm.setf(old);
     return;
   }
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of states" << NumStates() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of arcs" << NumArcs() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "initial state" << Start() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of final states" << NumFinal() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of input/output epsilons" << NumEpsilons() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of input epsilons" << NumInputEpsilons() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "# of output epsilons" << NumOutputEpsilons() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "input label multiplicity" << InputLabelMultiplicity() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "output label multiplicity" << OutputLabelMultiplicity()
         << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   std::string arc_type = "";
   if (ArcFilterType() == "epsilon")
     arc_type = "epsilon ";
@@ -48,54 +65,89 @@ void FstInfo::Info() const {
   else if (ArcFilterType() == "oepsilon")
     arc_type = "output-epsilon ";
   const auto accessible_label = "# of " + arc_type + "accessible states";
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << accessible_label << NumAccessible() << std::endl;
   const auto coaccessible_label = "# of " + arc_type + "coaccessible states";
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << coaccessible_label << NumCoAccessible() << std::endl;
   const auto connected_label = "# of " + arc_type + "connected states";
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << connected_label << NumConnected() << std::endl;
   const auto numcc_label = "# of " + arc_type + "connected components";
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << numcc_label << NumCc() << std::endl;
   const auto numscc_label = "# of " + arc_type + "strongly conn components";
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << numscc_label << NumScc() << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "input matcher"
         << (InputMatchType() == MATCH_INPUT
                 ? 'y'
                 : InputMatchType() == MATCH_NONE ? 'n' : '?')
         << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "output matcher"
         << (OutputMatchType() == MATCH_OUTPUT
                 ? 'y'
                 : OutputMatchType() == MATCH_NONE ? 'n' : '?')
         << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "input lookahead" << (InputLookAhead() ? 'y' : 'n') << std::endl;
-  ostrm.width(50);
+  ostrm.width(kWidth);
   ostrm << "output lookahead" << (OutputLookAhead() ? 'y' : 'n') << std::endl;
+  PrintProperties(ostrm, Properties());
+  ostrm.setf(old);
+}
+
+void PrintProperties(std::ostream &ostrm, const uint64 properties) {
   uint64 prop = 1;
   for (auto i = 0; i < 64; ++i, prop <<= 1) {
     if (prop & kBinaryProperties) {
-      char value = 'n';
-      if (Properties() & prop) value = 'y';
-      ostrm.width(50);
+      const char value = properties & prop ? 'y' : 'n';
+      ostrm.width(kWidth);
       ostrm << PropertyNames[i] << value << std::endl;
     } else if (prop & kPosTrinaryProperties) {
       char value = '?';
-      if (Properties() & prop) {
+      if (properties & prop) {
         value = 'y';
-      } else if (Properties() & prop << 1) {
+      } else if (properties & prop << 1) {
         value = 'n';
       }
-      ostrm.width(50);
+      ostrm.width(kWidth);
       ostrm << PropertyNames[i] << value << std::endl;
     }
   }
+}
+
+void PrintHeader(std::ostream &ostrm, const FstHeader &header) {
+  const auto old = ostrm.setf(std::ios::left);
+  ostrm.width(kWidth);
+  ostrm << "fst type" << header.FstType() << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "arc type" << header.ArcType() << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "version" << header.Version() << std::endl;
+
+  // Flags
+  const auto flags = header.GetFlags();
+  ostrm.width(kWidth);
+  ostrm << "input symbol table" << (flags & FstHeader::HAS_ISYMBOLS ? 'y' : 'n')
+        << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "output symbol table"
+        << (flags & FstHeader::HAS_OSYMBOLS ? 'y' : 'n') << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "aligned" << (flags & FstHeader::IS_ALIGNED ? 'y' : 'n')
+        << std::endl;
+
+  ostrm.width(kWidth);
+  ostrm << "initial state" << header.Start() << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "# of states" << header.NumStates() << std::endl;
+  ostrm.width(kWidth);
+  ostrm << "# of arcs" << header.NumArcs() << std::endl;
+
+  PrintProperties(ostrm, header.Properties());
   ostrm.setf(old);
 }
 
index f8e3cc1..6f5450c 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index be3fc80..adcda97 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e6e836b..8716992 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 23cb792..e0597f0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index ff15d55..147ac72 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
 namespace fst {
 namespace script {
 
-FstClass *Map(const FstClass &ifst, MapType map_type, float delta, double power,
-              const WeightClass &weight) {
+std::unique_ptr<FstClass> Map(const FstClass &ifst, MapType map_type,
+                              float delta, double power,
+                              const WeightClass &weight) {
   if (!ifst.WeightTypesMatch(weight, "Map")) return nullptr;
   MapInnerArgs iargs(ifst, map_type, delta, power, weight);
   MapArgs args(iargs);
   Apply<Operation<MapArgs>>("Map", ifst.ArcType(), &args);
-  return args.retval;
+  return std::move(args.retval);
 }
 
 REGISTER_FST_OPERATION_3ARCS(Map, MapArgs);
index 96e5ed8..d4d46e7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 05dd478..047db4e 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
@@ -13,8 +27,8 @@ void Print(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
            const SymbolTable *ssyms, bool accept, bool show_weight_one,
            const std::string &missing_sym) {
   const auto sep = FLAGS_fst_field_separator.substr(0, 1);
-  PrintArgs args(fst, isyms, osyms, ssyms, accept, show_weight_one, ostrm, dest,
-                 sep, missing_sym);
+  PrintArgs args{fst, isyms, osyms, ssyms, accept, show_weight_one, ostrm, dest,
+                 sep, missing_sym};
   Apply<Operation<PrintArgs>>("Print", fst.ArcType(), &args);
 }
 
index 80d4858..74e67c4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 70cc150..c21be7b 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 056b9a3..9097a50 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 40dcf5e..e182d59 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f0b10f7..9334cfb 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f27ad9a..a4e3fd9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index c78e1cb..52eb32d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 066e4ac..08cc3e9 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index bd4be66..b7ccd11 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e9886dd..7ebe7d0 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f958037..ec213b7 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 09d4f4f..a7e8157 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 6a258b8..2204149 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index f40e47b..d6c6833 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index b71b7af..4e03751 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index faf5021..da946cf 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index e264b28..ca2d82d 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 367cd74..6393c1f 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index 70e0ef4..0430e70 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
index b98c4d2..a8d284d 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index ed04731..e478633 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
index 08a329a..190dcd6 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -66,7 +80,6 @@ using fst::ConstFst;
 using fst::CustomArc;
 using fst::EditFst;
 using fst::FstTester;
-using fst::MatcherFst;
 using fst::StdArc;
 using fst::StdArcLookAheadFst;
 using fst::TrivialArcCompactor;
@@ -78,7 +91,7 @@ int main(int argc, char **argv) {
   std::set_new_handler(FailedNewHandler);
   SET_FLAGS(argv[0], &argc, &argv, true);
 
-  // VectorFst<StdArc> tests
+  LOG(INFO) << "Testing VectorFst<StdArc>.";
   {
     for (const size_t num_states : {0, 1, 2, 3, 128}) {
       FstTester<VectorFst<StdArc>> std_vector_tester(num_states);
@@ -90,7 +103,7 @@ int main(int argc, char **argv) {
       std_vector_tester.TestMutable();
     }
 
-    // Test with a default-constructed Fst, not a copied Fst.
+    LOG(INFO) << "Testing empty StdVectorFst.";
     FstTester<VectorFst<StdArc>> empty_tester(/*num_states=*/0);
     {
       const VectorFst<StdArc> empty_fst;
@@ -106,7 +119,7 @@ int main(int argc, char **argv) {
     }
   }
 
-  // ConstFst<StdArc> tests
+  LOG(INFO) << "Testing ConstFst<StdArc>.";
   {
     FstTester<ConstFst<StdArc>> std_const_tester;
     std_const_tester.TestBase();
@@ -115,7 +128,7 @@ int main(int argc, char **argv) {
     std_const_tester.TestIO();
   }
 
-  // CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>
+  LOG(INFO) << "Testing CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>.";
   {
     FstTester<CompactArcFst<StdArc, TrivialArcCompactor<StdArc>>>
         std_compact_tester;
@@ -125,7 +138,7 @@ int main(int argc, char **argv) {
     std_compact_tester.TestIO();
   }
 
-  // CompactFst<StdArc, TrivialArcCompactor<StdArc>>
+  LOG(INFO) << "Testing CompactFst<StdArc, TrivialArcCompactor<StdArc>>.";
   {
     for (const size_t num_states : {0, 1, 2, 3, 128}) {
       FstTester<CompactFst<StdArc, TrivialCompactor<StdArc>>>
@@ -136,7 +149,16 @@ int main(int argc, char **argv) {
       std_compact_tester.TestIO();
     }
 
-    // TODO(jrosenstock): Add tests on default-constructed Fst.
+    LOG(INFO) << "Testing empty CompactFst.";
+    FstTester<CompactFst<StdArc, TrivialCompactor<StdArc>>> empty_tester(
+        /*num_states=*/0);
+    {
+      const CompactFst<StdArc, TrivialCompactor<StdArc>> empty_fst;
+      empty_tester.TestBase(empty_fst);
+      empty_tester.TestExpanded(empty_fst);
+      empty_tester.TestCopy(empty_fst);
+      empty_tester.TestIO(empty_fst);
+    }
   }
 
   // VectorFst<CustomArc> tests
index 0b93afe..04e75f4 100644 (file)
@@ -1,3 +1,17 @@
+// Copyright 2005-2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the 'License');
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
@@ -253,9 +267,6 @@ void TestSparsePowerWeightGetSetValue() {
 // If this test fails, it is possible that x == x will not
 // hold for FloatWeight, breaking NaturalLess and probably more.
 // To trigger these failures, use g++ -O -m32 -mno-sse.
-// Google-only...
-// This will never fail in google3, as those options aren't used.
-// ...Google-only
 template <class T>
 bool FloatEqualityIsReflexive(T m) {
   // The idea here is that x is spilled to memory, but
@@ -452,6 +463,13 @@ int main(int argc, char **argv) {
   WeightTester<LogLogExpectationWeight, LogLogExpectationWeightGenerate>
       log_log_expectation_tester(log_log_expectation_generate);
 
+  using RealRealExpectationWeight = ExpectationWeight<LogWeight, LogWeight>;
+  using RealRealExpectationWeightGenerate =
+      WeightGenerate<RealRealExpectationWeight>;
+  RealRealExpectationWeightGenerate real_real_expectation_generate(FLAGS_seed);
+  WeightTester<RealRealExpectationWeight, RealRealExpectationWeightGenerate>
+      real_real_expectation_tester(real_real_expectation_generate);
+
   using LogLogSparseExpectationWeight =
       ExpectationWeight<LogWeight, LogSparsePowerWeight>;
   using LogLogSparseExpectationWeightGenerate =
@@ -493,15 +511,16 @@ int main(int argc, char **argv) {
   tropical_lexicographic_tester.Test(FLAGS_repeat);
   tropical_cube_tester.Test(FLAGS_repeat);
   log_sparse_power_tester.Test(FLAGS_repeat);
-  log_log_expectation_tester.Test(FLAGS_repeat, false);
-  tropical_union_tester.Test(FLAGS_repeat, false);
+  log_log_expectation_tester.Test(FLAGS_repeat);
+  real_real_expectation_tester.Test(FLAGS_repeat);
+  tropical_union_tester.Test(FLAGS_repeat);
 
   // Nested composite.
   first_nested_product_tester.Test(FLAGS_repeat);
   second_nested_product_tester.Test(5);
   nested_product_cube_tester.Test(FLAGS_repeat);
   sparse_nested_product_cube_tester.Test(FLAGS_repeat);
-  log_log_sparse_expectation_tester.Test(FLAGS_repeat, false);
+  log_log_sparse_expectation_tester.Test(FLAGS_repeat);
 
   // ... and tests composite weight I/O without parentheses.
   FLAGS_fst_weight_parentheses = "";
@@ -512,12 +531,12 @@ int main(int argc, char **argv) {
   tropical_lexicographic_tester.Test(FLAGS_repeat);
   tropical_cube_tester.Test(FLAGS_repeat);
   log_sparse_power_tester.Test(FLAGS_repeat);
-  log_log_expectation_tester.Test(FLAGS_repeat, false);
-  tropical_union_tester.Test(FLAGS_repeat, false);
+  log_log_expectation_tester.Test(FLAGS_repeat);
+  tropical_union_tester.Test(FLAGS_repeat);
 
   // Nested composite.
   second_nested_product_tester.Test(FLAGS_repeat);
-  log_log_sparse_expectation_tester.Test(FLAGS_repeat, false);
+  log_log_sparse_expectation_tester.Test(FLAGS_repeat);
 
   TestPowerWeightGetSetValue();
   TestSparsePowerWeightGetSetValue();
index b8521a4..89dba1e 100755 (executable)
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by