Imported Upstream version 1.7.3 upstream/1.7.3
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
352 files changed:
BUILD.bazel
Makefile.am
Makefile.in
NEWS
README
WORKSPACE [new file with mode: 0644]
configure
configure.ac
ltmain.sh
m4/libtool.m4
src/bin/fstarcsort-main.cc
src/bin/fstclosure-main.cc
src/bin/fstcompile-main.cc
src/bin/fstcompose-main.cc
src/bin/fstconcat-main.cc
src/bin/fstconnect-main.cc
src/bin/fstconvert-main.cc
src/bin/fstdeterminize-main.cc
src/bin/fstdifference-main.cc
src/bin/fstdisambiguate-main.cc
src/bin/fstdraw-main.cc
src/bin/fstencode-main.cc
src/bin/fstepsnormalize-main.cc
src/bin/fstequal-main.cc
src/bin/fstequivalent-main.cc
src/bin/fstinfo-main.cc
src/bin/fstintersect-main.cc
src/bin/fstinvert-main.cc
src/bin/fstisomorphic-main.cc
src/bin/fstmap-main.cc
src/bin/fstminimize-main.cc
src/bin/fstprint-main.cc
src/bin/fstproject-main.cc
src/bin/fstprune-main.cc
src/bin/fstpush-main.cc
src/bin/fstrandgen-main.cc
src/bin/fstrelabel-main.cc
src/bin/fstreplace-main.cc
src/bin/fstreverse-main.cc
src/bin/fstreweight-main.cc
src/bin/fstrmepsilon-main.cc
src/bin/fstshortestdistance-main.cc
src/bin/fstshortestpath-main.cc
src/bin/fstsymbols-main.cc
src/bin/fstsynchronize-main.cc
src/bin/fsttopsort-main.cc
src/bin/fstunion-main.cc
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 [moved from src/extensions/compress/compress-script.cc with 58% similarity]
src/extensions/compress/fstcompress-main.cc [new file with mode: 0644]
src/extensions/compress/fstcompress.cc
src/extensions/compress/fstrandmod.cc [deleted file]
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/far/Makefile.am
src/extensions/far/Makefile.in
src/extensions/far/far-class.cc
src/extensions/far/farcompilestrings-main.cc [new file with mode: 0644]
src/extensions/far/farcompilestrings.cc
src/extensions/far/farcreate-main.cc [new file with mode: 0644]
src/extensions/far/farcreate.cc
src/extensions/far/farequal-main.cc [new file with mode: 0644]
src/extensions/far/farequal.cc
src/extensions/far/farextract-main.cc [new file with mode: 0644]
src/extensions/far/farextract.cc
src/extensions/far/farinfo-main.cc [new file with mode: 0644]
src/extensions/far/farinfo.cc
src/extensions/far/farisomorphic-main.cc [new file with mode: 0644]
src/extensions/far/farisomorphic.cc
src/extensions/far/farprintstrings-main.cc [new file with mode: 0644]
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 [new file with mode: 0644]
src/extensions/linear/fstlinear.cc
src/extensions/linear/fstloglinearapply-main.cc [new file with mode: 0644]
src/extensions/linear/fstloglinearapply.cc
src/extensions/linear/linearscript.cc
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/mpdt/mpdtcompose-main.cc [new file with mode: 0644]
src/extensions/mpdt/mpdtcompose.cc
src/extensions/mpdt/mpdtexpand-main.cc [new file with mode: 0644]
src/extensions/mpdt/mpdtexpand.cc
src/extensions/mpdt/mpdtinfo-main.cc [new file with mode: 0644]
src/extensions/mpdt/mpdtinfo.cc
src/extensions/mpdt/mpdtreverse-main.cc [new file with mode: 0644]
src/extensions/mpdt/mpdtreverse.cc
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
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 [new file with mode: 0644]
src/extensions/pdt/pdtcompose.cc
src/extensions/pdt/pdtexpand-main.cc [new file with mode: 0644]
src/extensions/pdt/pdtexpand.cc
src/extensions/pdt/pdtinfo-main.cc [new file with mode: 0644]
src/extensions/pdt/pdtinfo.cc
src/extensions/pdt/pdtreplace-main.cc [new file with mode: 0644]
src/extensions/pdt/pdtreplace.cc
src/extensions/pdt/pdtreverse-main.cc [new file with mode: 0644]
src/extensions/pdt/pdtreverse.cc
src/extensions/pdt/pdtscript.cc
src/extensions/pdt/pdtshortestpath-main.cc [new file with mode: 0644]
src/extensions/pdt/pdtshortestpath.cc
src/extensions/python/basictypes.pxd
src/extensions/python/fst.pxd
src/extensions/python/pywrapfst.cc
src/extensions/python/pywrapfst.pxd
src/extensions/python/pywrapfst.pyx
src/extensions/special/Makefile.am
src/extensions/special/Makefile.in
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/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/const-fst.h
src/include/fst/disambiguate.h
src/include/fst/edit-fst.h
src/include/fst/encode.h
src/include/fst/equivalent.h
src/include/fst/expanded-fst.h
src/include/fst/expander-cache.h [new file with mode: 0644]
src/include/fst/expectation-weight.h
src/include/fst/extensions/compress/compress-script.h [deleted file]
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/compress/compressscript.h [new file with mode: 0644]
src/include/fst/extensions/compress/elias.h
src/include/fst/extensions/compress/gzfile.h
src/include/fst/extensions/compress/randmod.h [deleted file]
src/include/fst/extensions/far/compile-strings.h
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/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/mpdt/info.h
src/include/fst/extensions/mpdt/mpdt.h
src/include/fst/extensions/mpdt/read_write_utils.h
src/include/fst/extensions/ngram/ngram-fst.h
src/include/fst/extensions/ngram/nthbit.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/pdtscript.h
src/include/fst/extensions/pdt/replace.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/flags.h
src/include/fst/float-weight.h
src/include/fst/fst-decl.h
src/include/fst/fst.h
src/include/fst/generic-register.h
src/include/fst/icu.h
src/include/fst/isomorphic.h
src/include/fst/label-reachable.h
src/include/fst/lexicographic-weight.h
src/include/fst/lock.h
src/include/fst/log.h
src/include/fst/lookahead-matcher.h
src/include/fst/mapped-file.h
src/include/fst/matcher-fst.h
src/include/fst/minimize.h
src/include/fst/mutable-fst.h
src/include/fst/power-weight-mappers.h [new file with mode: 0644]
src/include/fst/power-weight.h
src/include/fst/product-weight.h
src/include/fst/properties.h
src/include/fst/queue.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/reverse.h
src/include/fst/reweight.h
src/include/fst/rmepsilon.h
src/include/fst/script/arciterator-class.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/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/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/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/prune.h
src/include/fst/script/push.h
src/include/fst/script/randequivalent.h
src/include/fst/script/randgen.h
src/include/fst/script/register.h
src/include/fst/script/relabel.h
src/include/fst/script/reverse.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/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-path.h
src/include/fst/signed-log-weight.h
src/include/fst/sparse-power-weight.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/fst_test.h
src/include/fst/test/weight-tester.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/weight.h
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/compat.cc
src/lib/flags.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/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/fst_test.cc

index 7a1d7a0..368695a 100644 (file)
@@ -18,6 +18,11 @@ licenses(["notice"])  # Apache 2.0
 
 exports_files(["COPYING"])
 
+config_setting(
+    name = "has_absl",
+    values = {"define": "absl=1"},
+)
+
 prefix_dir = "src/"
 
 static_binary = 1
@@ -268,7 +273,15 @@ cc_library(
         prefix_dir + "include/fst/log.h",
         prefix_dir + "include/fst/types.h",
     ],
+    defines = select({
+        ":has_absl": ["OPENFST_HAS_ABSL=1"],
+        "//conditions:default": [],
+    }),
     includes = [prefix_dir + "include"],
+    deps = select({
+        ":has_absl": ["@com_google_absl//absl/synchronization"],
+        "//conditions:default": [],
+    }),
 )
 
 # Core library tests (test/)
@@ -769,7 +782,10 @@ cc_library(
 [
     cc_binary(
         name = "far%s" % operation,
-        srcs = [prefix_dir + "extensions/far/far%s.cc" % operation],
+        srcs = [
+            prefix_dir + "extensions/far/far%s.cc" % operation,
+            prefix_dir + "extensions/far/far%s-main.cc" % operation,
+        ],
         linkstatic = static_binary,
         deps = [":farscript"],
     )
index 809d5c1..bf3404e 100644 (file)
@@ -1,4 +1,4 @@
 SUBDIRS = src
 ACLOCAL_AMFLAGS = -I m4
 
-EXTRA_DIST = BUILD.bazel
+EXTRA_DIST = BUILD.bazel WORKSPACE
index 0d29489..abe6d49 100644 (file)
@@ -345,7 +345,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 SUBDIRS = src
 ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = BUILD.bazel
+EXTRA_DIST = BUILD.bazel WORKSPACE
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
diff --git a/NEWS b/NEWS
index 6955538..462c01c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,10 @@
 OpenFst: Release 1.7
+   * Overloads Arc templatse with default weight argument (1.7.3)
+   * Makes Isomorphic more robust to nondeterminism (1.7.3)
+   * Adds default weight argument to SetFinal (1.7.3)
+   * Cleans up low-level logging (1.7.3)
+   * Adds power-weight mappers (1.7.3)
+   * Adds expander cache (1.7.3)
    * Fixes bug with coinaccessible states in NaturalAStarEstimate (1.7.2)
    * Optionally allows building with Bazel (1.7.2)
    * Simplifies string printing interface (1.7.2)
@@ -6,29 +12,29 @@ OpenFst: Release 1.7
    * Adds NoMatchComposeFilter (1.7.2)
    * Removed static assertions that trigger bugs in GCC (1.7.1)
    * Evaluates many weight operations at compile-time (1.7.1)
+   * Improved use of move semantics, especially in cache-backed FSTs (1.7.0)
    * Adds configure-time test for float equality reflexivity (1.7.0)
-   * Adds additional overloads to Equals (1.7.0)
    * Removes volatile qualifiers from float weights (1.7.0)
-   * Improved use of move semantics, especially in cache-backed FSTs (1.7.0)
    * Protections for signedness in string compiler (1.7.0)
+   * Adds additional overloads to Equals (1.7.0)
    * Clean-up to weight constructors (1.7.0)
 
 OpenFst: Release 1.6
    * Optimized label lookup in SymbolTable (1.6.9)
+   * Fixed HashMatcher issues with SetState() and Find() consistency (1.6.8)
    * Fixed PROGRAM_FLAGS documentation string in binaries (1.6.8)
    * Fixed handling of symbol tables in EpsNormalize (1.6.8)
-   * Fixed HashMatcher issues with SetState() and Find() consistency (1.6.8)
    * Fixed error reporting when FST arc type unknown (1.6.8)
    * The `first_path` option to ShortestPath is now optimal for A* (1.6.7)
    * Renames SymbolTable::kNoSymbol to kNoSymbol (1.6.7)
    * Exposes PowerMapper to the scripting API (1.6.7)
    * Fixes linking of the special SOs (1.6.7)
-   * Fixes error handling in HashMatcher (1.6.6)
    * Adds kShortestDelta for operations dependent on shortest-distance (1.6.6)
    * Adds Python methods for (un)pickling and (de)serializing FSTs (1.6.6)
    * Adds constructive variants of Invert and Project (1.6.6)
    * Increases code sharing in MemoryPool/MemoryArena (1.6.6)
    * Improves consistency of matcher FST ownership (1.6.6)
+   * Fixes error handling in HashMatcher (1.6.6)
    * Adds non-trivial A* estimator class (1.6.6)
    * Prevents unreachable code generation in libfstscript (1.6.5)
    * Adds move constructors for non-trivial weight types (1.6.5)
@@ -45,40 +51,39 @@ OpenFst: Release 1.6
    * Properly sets return codes in FST binaries (1.6.3)
    * Eliminates StringWeight macros (1.6.3)
    * Finalizes most virtual method overrides (1.6.2)
-   * Fixes missing includes of <fst/log.h> (1.6.1)
    * Adds float format support to FST drawing (1.6.1)
-   * Extensive modernization for C++11 style (1.6.0)
-   * Many classes and constants moved into an internal namespace (1.6.0)
-   * Adds HashMatcher (1.6.0)
-   * Adds Member method to SymbolTable (1.6.0)
+   * Fixes missing includes of <fst/log.h> (1.6.1)
    * Adds the "special" extension and the fstspecial binary; this is similar to
      fstconvert but accepts arguments for specifying special labels (phi, rho,
      and sigma) of FSTs (1.6.0)
    * Exposes allow_negative_label option for Python symbol tables (1.6.0)
+   * Many classes and constants moved into an internal namespace (1.6.0)
+   * Extensive modernization for C++11 style (1.6.0)
+   * Adds Member method to SymbolTable (1.6.0)
+   * Adds HashMatcher (1.6.0)
 
 OpenFst: Release 1.5
-   * Added p-subsequential determinization (1.5.0)
    * Generalized epsilon normalization to non-functional case (1.5.0)
+   * Added multiple pushdown transducer (MPDT) support (1.5.0)
    * Added general gallic (plus is union) semiring (1.5.0)
+   * Added p-subsequential determinization (1.5.0)
+   * Fixed missing Isomorphic components (1.5.0)
    * Added FST compression extension (1.5.0)
-   * Added Python extension (1.5.0)
-   * Added multiple pushdown transducer (MPDT) support (1.5.0)
-   * Fixed Isomorphic function (1.5.0)
    * Added final method to matchers (1.5.0)
    * Fixed various compiler issues (1.5.0)
-   * Fixed missing Isomorphic components (1.5.0)
+   * Fixed Isomorphic function (1.5.0)
+   * Added Python extension (1.5.0)
    * Added UnionWeight (1.5.0)
-   * Added InputEpsilonMapper and OutputEpsilonMapper arc mappers (1.5.1)
-   * Added TrivialComposeFilter for more efficient composition when one
-     of the arguments is epsilon-free (1.5.1)
-   * Added properties bits kUnweightedCycles and kWeightedCycles (1.5.1)
    * Added missing const qualification to (1.5.1):
       - SymbolTableIterator access
       - EncodeMapper writing to file
       - EncodeMapper SymbolTable access
-   * Replaced internal custom reference-counting (RefCounter) with
-     C++11 smart pointers where possible, and fixed associated
-     reference-counting bugs (1.5.1)
+   * Added TrivialComposeFilter for more efficient composition when one
+     of the arguments is epsilon-free (1.5.1)
+   * Added InputEpsilonMapper and OutputEpsilonMapper arc mappers (1.5.1)
+   * Added properties bits kUnweightedCycles and kWeightedCycles (1.5.1)
+   * Replaced internal custom reference-counting (RefCounter) with C++11 smart
+     pointers where possible, and fixed reference-counting bugs (1.5.1)
    * When calling DeleteStates on a MutableFst with a shared impl, the impl
      is set to a new empty impl rather than copying and deleting (1.5.1)
    * Prepended `Pdt` to the Expand libraries and classes in the PDT
@@ -106,29 +111,29 @@ OpenFst: Release 1.5
       - Adds FST compilation from arclists (cf. fstcompile)
       - Adds FST printing and drawing
       - Adds FarReader and FarWriter classes.
-   * FarReader's GetFst method now returns a pointer (1.5.2)
-   * Fixed FSTERROR macro (1.5.2)
-   * Fixed build flags for dlopen (1.5.2)
    * Consolidated Python extension into single module (1.5.2)
+   * FarReader's GetFst method now returns a pointer (1.5.2)
    * Python add_arc now takes an Arc object (1.5.2)
-   * Adds optional minimization of non-deterministic FSTs (1.5.3)
-   * Mutation methods of the Python Fst object now support chaining (1.5.3)
+   * Fixed build flags for dlopen (1.5.2)
+   * Fixed FSTERROR macro (1.5.2)
    * Scripting API and Python weight objects now support semiring arithmetic
      (1.5.3)
-   * Adds RemoveSymbol method to SymbolTable (1.5.4)
+   * Mutation methods of the Python Fst object now support chaining (1.5.3)
+   * Adds optional minimization of non-deterministic FSTs (1.5.3)
+   * Adds check for error when opening files when compiling strings into FARs
+     (1.5.4)
    * Prevents underflow when using LogProbArcSelector in random generation
      (1.5.4)
+   * Adds routines for parsing string flags to the scripting API (1.5.4)
    * Makes random weight generators a single template class (1.5.4)
    * Makes weight Properties constexpr where possible (1.5.4)
-   * Adds check for error when opening files when compiling strings into FARs
-     (1.5.4)
-   * Adds routines for parsing string flags to the scripting API (1.5.4)
+   * Adds RemoveSymbol method to SymbolTable (1.5.4)
 
 OpenFst: Release 1.4
    * Port to C++11 (1.4.0)
-   * Disambiguate function added (1.4.0)
    * Isomorphic function added (1.4.0)
-   * Matcher interface augmented with Priority method.
+   * Disambiguate function added (1.4.0)
+   * Matcher interface augmented with Priority method
    * Special matchers (rho/sigma/phi) can match special symbols
      on both input FSTs in composition/intersection provided at each
      state pair they only match one side (1.4.0)
diff --git a/README b/README
index db23077..57de1ef 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-OpenFst: Release 1.7.2.
+OpenFst: Release 1.7.3.
 
 OpenFst is a library for constructing, combining, optimizing, and searching
 weighted finite-state transducers (FSTs).
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644 (file)
index 0000000..e18b187
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,15 @@
+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"],
+)
index 285a278..6364c9f 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.2.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.7.3.
 #
 # 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.2'
-PACKAGE_STRING='OpenFst 1.7.2'
+PACKAGE_VERSION='1.7.3'
+PACKAGE_STRING='OpenFst 1.7.3'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -1395,7 +1395,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.2 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.7.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1466,7 +1466,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.2:";;
+     short | recursive ) echo "Configuration of OpenFst 1.7.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1598,7 +1598,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.2
+OpenFst configure 1.7.3
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2039,7 +2039,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.2, which was
+It was created by OpenFst $as_me 1.7.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2902,7 +2902,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.2'
+ VERSION='1.7.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5938,7 +5938,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd*)
+netbsd* | netbsdelf*-gnu)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
   else
@@ -9611,6 +9611,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
   esac
 
   ld_shlibs=yes
@@ -9865,7 +9868,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -10535,6 +10538,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
        if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
+       link_all_deplibs=no
       else
        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -10556,7 +10560,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       esac
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -14565,7 +14581,7 @@ lt_prog_compiler_static_CXX=
            ;;
        esac
        ;;
-      netbsd*)
+      netbsd* | netbsdelf*-gnu)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -14940,6 +14956,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
       ;;
     esac
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs_CXX=no
+    ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -17458,7 +17489,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.2, which was
+This file was extended by OpenFst $as_me 1.7.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17524,7 +17555,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.2
+OpenFst config.status 1.7.3
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18760,7 +18791,6 @@ $as_echo X"$file" |
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
index ea450da..6ff5685 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([OpenFst], [1.7.2], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.7.3], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
index b6f1800..e4eda6d 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4.6
+VERSION="2.4.6 Debian-2.4.6-2.1"
 package_revision=2.4.6
 
 
@@ -64,7 +64,7 @@ package_revision=2.4.6
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
@@ -580,16 +580,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1091,85 +1091,181 @@ func_relative_path ()
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-         _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-       func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
       fi
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \  ]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
+
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-         ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-       func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  func_quotefast_eval ()
+  {
+    printf -v func_quotefast_eval_result %q "$1"
+  }
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
 
-    case $1 in
-      *[\\\`\"]*)
-       _G_arg=`$ECHO "$1" | $SED \
-           -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero ore more
+# specifiers listed below separated by ',' character.  This function returns two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         later used in func_quote to get output like: 'echo "a b"' instead of
+#         'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
     esac
 
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
         ;;
     esac
+}
 
-    func_quote_for_expand_result=$_G_arg
+
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1215,8 +1311,8 @@ func_show_eval ()
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1241,8 +1337,8 @@ func_show_eval_locale ()
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
@@ -1370,7 +1466,7 @@ func_lt_ver ()
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-12.13; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1530,6 +1626,8 @@ func_run_hooks ()
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1538,16 +1636,16 @@ func_run_hooks ()
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1557,10 +1655,16 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1570,9 +1674,11 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1581,25 +1687,37 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1611,16 +1729,32 @@ func_run_hooks ()
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1630,17 +1764,28 @@ func_options ()
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    fi
+
+    $_G_rc_options
 }
 
 
@@ -1649,9 +1794,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1661,10 +1806,14 @@ func_options_prep ()
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -1678,18 +1827,20 @@ func_parse_options ()
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -1704,7 +1855,10 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1757,15 +1911,25 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -1778,16 +1942,21 @@ func_validate_options ()
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
@@ -2068,12 +2237,12 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
+       version:        $progname $scriptversion Debian-2.4.6-2.1
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
 General help using GNU software: <http://www.gnu.org/gethelp/>."
     exit 0
 }
@@ -2270,6 +2439,8 @@ libtool_options_prep ()
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2293,11 +2464,18 @@ libtool_options_prep ()
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
+    fi
+
+    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2309,9 +2487,12 @@ libtool_parse_options ()
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2386,15 +2567,22 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         ;;
 
-       # An option not handled by this hook function:
-        *)             set dummy "$_G_opt" ${1+"$@"};  shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
+    fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -2451,8 +2639,8 @@ libtool_validate_options ()
     }
 
     # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3418,8 +3606,8 @@ func_mode_compile ()
       esac
     done
 
-    func_quote_for_eval "$libobj"
-    test "X$libobj" != "X$func_quote_for_eval_result" \
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3492,8 +3680,8 @@ compiler."
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_for_eval "$srcfile"
-    qsrcfile=$func_quote_for_eval_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4096,8 +4284,8 @@ func_mode_install ()
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_for_eval "$nonopt"
-      install_prog="$func_quote_for_eval_result "
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
       arg=$1
       shift
     else
@@ -4107,8 +4295,8 @@ func_mode_install ()
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_for_eval "$arg"
-    func_append install_prog "$func_quote_for_eval_result"
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4165,12 +4353,12 @@ func_mode_install ()
       esac
 
       # Aesthetically quote the argument.
-      func_quote_for_eval "$arg"
-      func_append install_prog " $func_quote_for_eval_result"
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
       if test -n "$arg2"; then
-       func_quote_for_eval "$arg2"
+       func_quote_arg pretty "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_for_eval_result"
+      func_append install_shared_prog " $func_quote_arg_result"
     done
 
     test -z "$install_prog" && \
@@ -4181,8 +4369,8 @@ func_mode_install ()
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-       func_quote_for_eval "$install_override_mode"
-       func_append install_shared_prog " -m $func_quote_for_eval_result"
+       func_quote_arg pretty "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_arg_result"
       fi
     fi
 
@@ -4478,8 +4666,8 @@ func_mode_install ()
                relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
                $opt_quiet || {
-                 func_quote_for_expand "$relink_command"
-                 eval "func_echo $func_quote_for_expand_result"
+                 func_quote_arg expand,pretty "$relink_command"
+                 eval "func_echo $func_quote_arg_result"
                }
                if eval "$relink_command"; then :
                  else
@@ -5258,7 +5446,8 @@ else
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5268,7 +5457,7 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6611,9 +6800,9 @@ func_mode_link ()
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_for_eval "$arg"
-      qarg=$func_quote_for_eval_unquoted_result
-      func_append libtool_args " $func_quote_for_eval_result"
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7211,20 +7400,15 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_for_eval "$flag"
-         func_append arg " $func_quote_for_eval_result"
-         func_append compiler_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+         func_append arg " $func_quote_arg_result"
+         func_append compiler_flags " $func_quote_arg_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
        arg=$func_stripname_result
        ;;
 
-      -Wl,--as-needed)
-       deplibs="$deplibs $arg"
-       continue
-       ;;
-
       -Wl,*)
        func_stripname '-Wl,' '' "$arg"
        args=$func_stripname_result
@@ -7232,10 +7416,10 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_for_eval "$flag"
-         func_append arg " $wl$func_quote_for_eval_result"
-         func_append compiler_flags " $wl$func_quote_for_eval_result"
-         func_append linker_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+         func_append arg " $wl$func_quote_arg_result"
+         func_append compiler_flags " $wl$func_quote_arg_result"
+         func_append linker_flags " $func_quote_arg_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -7259,8 +7443,8 @@ func_mode_link ()
 
       # -msg_* for osf cc
       -msg_*)
-       func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+       func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7277,12 +7461,15 @@ func_mode_link ()
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang/GCC memory and address sanitizer
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
-        func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*|-fsanitize=*)
+        func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7303,15 +7490,15 @@ func_mode_link ()
          continue
         else
          # Otherwise treat like 'Some other compiler flag' below
-         func_quote_for_eval "$arg"
-         arg=$func_quote_for_eval_result
+         func_quote_arg pretty "$arg"
+         arg=$func_quote_arg_result
         fi
        ;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
 
       *.$objext)
@@ -7431,8 +7618,8 @@ func_mode_link ()
       *)
        # Unknown arguments in both finalize_command and compile_command need
        # to be aesthetically quoted because they are evaled later.
-       func_quote_for_eval "$arg"
-       arg=$func_quote_for_eval_result
+       func_quote_arg pretty "$arg"
+       arg=$func_quote_arg_result
        ;;
       esac # arg
 
@@ -7529,7 +7716,6 @@ func_mode_link ()
 
     case $linkmode in
     lib)
-       as_needed_flag=
        passes="conv dlpreopen link"
        for file in $dlfiles $dlprefiles; do
          case $file in
@@ -7541,7 +7727,6 @@ func_mode_link ()
        done
        ;;
     prog)
-       as_needed_flag=
        compile_deplibs=
        finalize_deplibs=
        alldeplibs=false
@@ -7575,7 +7760,10 @@ func_mode_link ()
        case $pass in
        dlopen) libs=$dlfiles ;;
        dlpreopen) libs=$dlprefiles ;;
-       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       link)
+         libs="$deplibs %DEPLIBS%"
+         test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+         ;;
        esac
       fi
       if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7611,15 +7799,6 @@ func_mode_link ()
        lib=
        found=false
        case $deplib in
-       -Wl,--as-needed)
-         if test prog,link = "$linkmode,$pass" ||
-            test lib,link = "$linkmode,$pass"; then
-           as_needed_flag="$deplib "
-         else
-           deplibs="$deplib $deplibs"
-         fi
-         continue
-         ;;
        -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test prog,link = "$linkmode,$pass"; then
@@ -7903,19 +8082,19 @@ func_mode_link ()
            # It is a libtool convenience library, so add in its objects.
            func_append convenience " $ladir/$objdir/$old_library"
            func_append old_convenience " $ladir/$objdir/$old_library"
+           tmp_libs=
+           for deplib in $dependency_libs; do
+             deplibs="$deplib $deplibs"
+             if $opt_preserve_dup_deps; then
+               case "$tmp_libs " in
+               *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+               esac
+             fi
+             func_append tmp_libs " $deplib"
+           done
          elif test prog != "$linkmode" && test lib != "$linkmode"; then
            func_fatal_error "'$lib' is not a convenience library"
          fi
-         tmp_libs=
-         for deplib in $dependency_libs; do
-           deplibs="$deplib $deplibs"
-           if $opt_preserve_dup_deps; then
-             case "$tmp_libs " in
-             *" $deplib "*) func_append specialdeplibs " $deplib" ;;
-             esac
-           fi
-           func_append tmp_libs " $deplib"
-         done
          continue
        fi # $pass = conv
 
@@ -8839,6 +9018,9 @@ func_mode_link ()
            revision=$number_minor
            lt_irix_increment=no
            ;;
+         *)
+           func_fatal_configuration "$modename: unknown library version type '$version_type'"
+           ;;
          esac
          ;;
        no)
@@ -9949,8 +10131,8 @@ EOF
            for cmd in $concat_cmds; do
              IFS=$save_ifs
              $opt_quiet || {
-                 func_quote_for_expand "$cmd"
-                 eval "func_echo $func_quote_for_expand_result"
+                 func_quote_arg expand,pretty "$cmd"
+                 eval "func_echo $func_quote_arg_result"
              }
              $opt_dry_run || eval "$cmd" || {
                lt_exit=$?
@@ -10037,21 +10219,14 @@ EOF
          test "X$libobjs" = "X " && libobjs=
        fi
 
-       # A bit hacky. I had wanted to add \$as_needed_flag to archive_cmds instead, but that
-       # comes from libtool.m4 which is part of the project being built. This should put it
-       # in the right place though.
-       if test lib,link = "$linkmode,$pass" && test -n "$as_needed_flag"; then
-         libobjs=$as_needed_flag$libobjs
-       fi
-
        save_ifs=$IFS; IFS='~'
        for cmd in $cmds; do
          IFS=$sp$nl
          eval cmd=\"$cmd\"
          IFS=$save_ifs
          $opt_quiet || {
-           func_quote_for_expand "$cmd"
-           eval "func_echo $func_quote_for_expand_result"
+           func_quote_arg expand,pretty "$cmd"
+           eval "func_echo $func_quote_arg_result"
          }
          $opt_dry_run || eval "$cmd" || {
            lt_exit=$?
@@ -10276,8 +10451,8 @@ EOF
       compile_deplibs=$new_libs
 
 
-      func_append compile_command " $as_needed_flag $compile_deplibs"
-      func_append finalize_command " $as_needed_flag $finalize_deplibs"
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
 
       if test -n "$rpath$xrpath"; then
        # If the user specified any rpath flags, then add them.
@@ -10525,12 +10700,12 @@ EOF
          elif eval var_value=\$$var; test -z "$var_value"; then
            relink_command="$var=; export $var; $relink_command"
          else
-           func_quote_for_eval "$var_value"
-           relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+           func_quote_arg pretty "$var_value"
+           relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
          fi
        done
-       relink_command="(cd `pwd`; $relink_command)"
-       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+       func_quote_arg pretty,unquoted "(cd `pwd`; $relink_command)"
+       relink_command=$func_quote_arg_unquoted_result
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10770,13 +10945,14 @@ EOF
        elif eval var_value=\$$var; test -z "$var_value"; then
          relink_command="$var=; export $var; $relink_command"
        else
-         func_quote_for_eval "$var_value"
-         relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+         func_quote_arg pretty,unquoted "$var_value"
+         relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
        fi
       done
       # Quote the link command for shipping.
       relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      func_quote_arg pretty,unquoted "$relink_command"
+      relink_command=$func_quote_arg_unquoted_result
       if test yes = "$hardcode_automatic"; then
        relink_command=
       fi
index a3bc337..ee80844 100644 (file)
@@ -728,7 +728,6 @@ _LT_CONFIG_SAVE_COMMANDS([
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
@@ -2887,6 +2886,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -3546,7 +3557,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd*)
+netbsd* | netbsdelf*-gnu)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
@@ -4424,7 +4435,7 @@ m4_if([$1], [CXX], [
            ;;
        esac
        ;;
-      netbsd*)
+      netbsd* | netbsdelf*-gnu)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4936,6 +4947,9 @@ m4_if([$1], [CXX], [
       ;;
     esac
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -4998,6 +5012,9 @@ dnl Note also adjust exclude_expsyms for C++ above.
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
   esac
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5252,7 +5269,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -5773,6 +5790,7 @@ _LT_EOF
        if test yes = "$lt_cv_irix_exported_symbol"; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
+       _LT_TAGVAR(link_all_deplibs, $1)=no
       else
        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5794,7 +5812,7 @@ _LT_EOF
       esac
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
index b1a67ca..e5fc71a 100644 (file)
@@ -4,7 +4,6 @@
 // Sorts arcs of an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -19,7 +18,7 @@ int fstarcsort_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::MutableFstClass;
 
-  string usage = "Sorts arcs of an FST.\n\n  Usage: ";
+  std::string usage = "Sorts arcs of an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -31,9 +30,10 @@ int fstarcsort_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name =
+  const std::string in_name =
       (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 4743a0b..dca66c8 100644 (file)
@@ -4,7 +4,6 @@
 // Creates the Kleene closure of an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -18,7 +17,7 @@ int fstclosure_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::MutableFstClass;
 
-  string usage = "Creates the Kleene closure of an FST.\n\n  Usage: ";
+  std::string usage = "Creates the Kleene closure of an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -29,8 +28,10 @@ int fstclosure_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 99c5009..dc45cc2 100644 (file)
@@ -4,7 +4,6 @@
 // Creates binary FSTs from simple text format used by AT&T.
 
 #include <cstring>
-
 #include <fstream>
 #include <istream>
 #include <memory>
@@ -30,7 +29,8 @@ int fstcompile_main(int argc, char **argv) {
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
 
-  string usage = "Creates binary FSTs from simple text format.\n\n  Usage: ";
+  std::string usage =
+      "Creates binary FSTs from simple text format.\n\n  Usage: ";
   usage += argv[0];
   usage += " [text.fst [binary.fst]]\n";
 
@@ -41,7 +41,7 @@ int fstcompile_main(int argc, char **argv) {
     return 1;
   }
 
-  string source = "standard input";
+  std::string source = "standard input";
   std::ifstream fstrm;
   if (argc > 1 && strcmp(argv[1], "-") != 0) {
     fstrm.open(argv[1]);
@@ -73,7 +73,7 @@ int fstcompile_main(int argc, char **argv) {
     if (!ssyms) return 1;
   }
 
-  const string dest = argc > 2 ? argv[2] : "";
+  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,
index df5afd7..e1de5d7 100644 (file)
@@ -4,7 +4,6 @@
 // Composes two FSTs.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -23,7 +22,7 @@ int fstcompose_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Composes two FSTs.\n\n  Usage: ";
+  std::string usage = "Composes two FSTs.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst [out.fst]\n";
 
@@ -34,10 +33,11 @@ int fstcompose_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
-  const string in2_name =
+  const std::string in1_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  const std::string in2_name =
       (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string out_name =
+      (argc > 3 && (strcmp(argv[3], "-") != 0)) ? argv[3] : "";
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 07609ec..436ba35 100644 (file)
@@ -4,7 +4,6 @@
 // Concatenates two FSTs.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -17,7 +16,7 @@ int fstconcat_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::MutableFstClass;
 
-  string usage = "Concatenates two FSTs.\n\n  Usage: ";
+  std::string usage = "Concatenates two FSTs.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst [out.fst]\n";
 
@@ -28,9 +27,10 @@ int fstconcat_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 6de987d..2bfacf2 100644 (file)
@@ -5,7 +5,6 @@
 // FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -17,7 +16,8 @@ int fstconnect_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::MutableFstClass;
 
-  string usage = "Removes useless states and arcs from an FST.\n\n  Usage: ";
+  std::string usage =
+      "Removes useless states and arcs from an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -28,8 +28,10 @@ int fstconnect_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 60dc7ab..a7aa447 100644 (file)
@@ -4,7 +4,6 @@
 // Converts an FST to another type.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -17,7 +16,7 @@ int fstconvert_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
 
-  string usage = "Converts an FST to another type.\n\n  Usage: ";
+  std::string usage = "Converts an FST to another type.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -28,8 +27,10 @@ int fstconvert_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 53e3e1d..efade36 100644 (file)
@@ -4,7 +4,6 @@
 // Determinizes an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -26,7 +25,7 @@ int fstdeterminize_main(int argc, char **argv) {
   using fst::script::VectorFstClass;
   using fst::script::WeightClass;
 
-  string usage = "Determinizes an FST.\n\n  Usage: ";
+  std::string usage = "Determinizes an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -44,8 +43,10 @@ int fstdeterminize_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index d31fb9e..d0dd4f1 100644 (file)
@@ -4,7 +4,6 @@
 // Subtracts an unweighted DFA from an FSA.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -23,7 +22,7 @@ int fstdifference_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Subtracts an unweighted DFA from an FSA.\n\n  Usage: ";
+  std::string usage = "Subtracts an unweighted DFA from an FSA.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst [out.fst]\n";
 
@@ -34,9 +33,10 @@ int fstdifference_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index b906af3..d439e03 100644 (file)
@@ -4,7 +4,6 @@
 // Disambiguates an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -22,7 +21,7 @@ int fstdisambiguate_main(int argc, char **argv) {
   using fst::script::VectorFstClass;
   using fst::script::WeightClass;
 
-  string usage = "Disambiguates an FST.\n\n  Usage: ";
+  std::string usage = "Disambiguates an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -33,8 +32,10 @@ int fstdisambiguate_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index d28299e..b1dfbad 100644 (file)
@@ -4,7 +4,6 @@
 // Draws a binary FSTs in the Graphviz dot text format.
 
 #include <cstring>
-
 #include <fstream>
 #include <memory>
 #include <ostream>
@@ -38,7 +37,7 @@ int fstdraw_main(int argc, char **argv) {
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
 
-  string usage = "Prints out binary FSTs in dot text format.\n\n  Usage: ";
+  std::string usage = "Prints out binary FSTs in dot text format.\n\n  Usage: ";
   usage += argv[0];
   usage += " [binary.fst [text.dot]]\n";
 
@@ -49,20 +48,21 @@ int fstdraw_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string in_name =
+      argc > 1 && strcmp(argv[1], "-") != 0 ? argv[1] : "";
 
   std::unique_ptr<FstClass> fst(FstClass::Read(in_name));
   if (!fst) return 1;
 
-  string dest = "stdout";
+  const std::string out_name =
+      argc > 2 && strcmp(argv[2], "-") != 0 ? argv[2] : "";
   std::ofstream fstrm;
-  if (argc == 3) {
-    fstrm.open(argv[2]);
+  if (!out_name.empty()) {
+    fstrm.open(out_name);
     if (!fstrm) {
-      LOG(ERROR) << argv[0] << ": Open failed, file = " << argv[2];
+      LOG(ERROR) << argv[0] << ": Open failed, file = " << out_name;
       return 1;
     }
-    dest = argv[2];
   }
   std::ostream &ostrm = fstrm.is_open() ? fstrm : std::cout;
 
@@ -94,6 +94,8 @@ int fstdraw_main(int argc, char **argv) {
     osyms.reset(fst->OutputSymbols()->Copy());
   }
 
+  // "dest" is only used for the name of the file in error messages.
+  const std::string dest = out_name.empty() ? "stdout" : out_name;
   s::DrawFst(*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,
index 9441480..a8340e5 100644 (file)
@@ -4,7 +4,6 @@
 // Encode transducer labels and/or weights.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -23,7 +22,7 @@ int fstencode_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::MutableFstClass;
 
-  string usage = "Encodes transducer labels and/or weights.\n\n  Usage: ";
+  std::string usage = "Encodes transducer labels and/or weights.\n\n  Usage: ";
   usage += argv[0];
   usage += " in.fst codex [out.fst]\n";
 
@@ -34,9 +33,10 @@ int fstencode_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string codex_name = argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in_name = (strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string codex_name = argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index acadd17..4308da8 100644 (file)
@@ -4,7 +4,6 @@
 // Epsilon-normalizes an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -19,7 +18,7 @@ int fstepsnormalize_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Epsilon normalizes an FST.\n\n  Usage: ";
+  std::string usage = "Epsilon normalizes an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -30,8 +29,10 @@ int fstepsnormalize_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index f7b2248..22e01ae 100644 (file)
@@ -4,7 +4,6 @@
 // Two FSTS are equal iff their exit status is zero.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -18,7 +17,8 @@ int fstequal_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
 
-  string usage = "Two FSTs are equal iff the exit status is zero.\n\n  Usage: ";
+  std::string usage =
+      "Two FSTs are equal iff the exit status is zero.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst\n";
 
@@ -29,8 +29,8 @@ int fstequal_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 8b4b151..4be09e6 100644 (file)
@@ -4,7 +4,6 @@
 // Two DFAs are equivalent iff their exit status is zero.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -26,7 +25,7 @@ int fstequivalent_main(int argc, char **argv) {
   using fst::RandGenOptions;
   using fst::script::FstClass;
 
-  string usage =
+  std::string usage =
       "Two DFAs are equivalent iff the exit status is zero.\n\n"
       "  Usage: ";
   usage += argv[0];
@@ -39,8 +38,8 @@ int fstequivalent_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 9877e07..c8685d2 100644 (file)
@@ -5,7 +5,6 @@
 // and arcs and property values (see properties.h).
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -22,7 +21,7 @@ int fstinfo_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
 
-  string usage = "Prints out information about an FST.\n\n  Usage: ";
+  std::string usage = "Prints out information about an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst]\n";
 
@@ -33,7 +32,7 @@ int fstinfo_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name =
+  const std::string in_name =
       (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
index 9d1c9a3..6008c4d 100644 (file)
@@ -4,7 +4,6 @@
 // Intersects two FSTs.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -22,7 +21,7 @@ int fstintersect_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Intersects two FSAs.\n\n  Usage: ";
+  std::string usage = "Intersects two FSAs.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst [out.fst]\n";
   usage += "  Flags: connect\n";
@@ -34,9 +33,10 @@ int fstintersect_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 61e858a..3d00cc0 100644 (file)
@@ -4,7 +4,6 @@
 // Inverts a transduction.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -15,7 +14,7 @@ int fstinvert_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::MutableFstClass;
 
-  string usage = "Inverts a transduction.\n\n  Usage: ";
+  std::string usage = "Inverts a transduction.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -26,8 +25,10 @@ int fstinvert_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 2b7c6bf..d54a150 100644 (file)
@@ -6,7 +6,6 @@
 // automata.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -20,7 +19,7 @@ int fstisomorphic_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::FstClass;
 
-  string usage =
+  std::string usage =
       "Two FSTs are isomorphic iff the exit status is zero.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst\n";
@@ -32,8 +31,8 @@ int fstisomorphic_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
 
   if (in1_name.empty() && in2_name.empty()) {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index 56a8198..72cc8cc 100644 (file)
@@ -4,7 +4,6 @@
 // Applies an operation to each arc of an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -23,7 +22,8 @@ int fstmap_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::WeightClass;
 
-  string usage = "Applies an operation to each arc of an FST.\n\n  Usage: ";
+  std::string usage =
+      "Applies an operation to each arc of an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -34,8 +34,10 @@ int fstmap_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index f189f94..cb50711 100644 (file)
@@ -4,7 +4,6 @@
 // Minimizes a deterministic FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -20,7 +19,7 @@ int fstminimize_main(int argc, char **argv) {
   using fst::script::MutableFstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Minimizes a deterministic FST.\n\n  Usage: ";
+  std::string usage = "Minimizes a deterministic FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out1.fst [out2.fst]]]\n";
 
@@ -31,10 +30,11 @@ int fstminimize_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out1_name =
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out1_name =
       (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
-  const string out2_name =
+  const std::string out2_name =
       (argc > 3 && strcmp(argv[3], "-") != 0) ? argv[3] : "";
 
   if (out1_name.empty() && out2_name.empty() && argc > 3) {
index 95884dd..bf7be38 100644 (file)
@@ -4,7 +4,6 @@
 // Prints out binary FSTs in simple text format used by AT&T.
 
 #include <cstring>
-
 #include <fstream>
 #include <memory>
 #include <ostream>
@@ -31,7 +30,8 @@ int fstprint_main(int argc, char **argv) {
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
 
-  string usage = "Prints out binary FSTs in simple text format.\n\n  Usage: ";
+  std::string usage =
+      "Prints out binary FSTs in simple text format.\n\n  Usage: ";
   usage += argv[0];
   usage += " [binary.fst [text.fst]]\n";
 
@@ -42,13 +42,15 @@ int fstprint_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> fst(FstClass::Read(in_name));
   if (!fst) return 1;
 
-  string dest = "standard output";
+  std::string dest = "standard output";
   std::ofstream fstrm;
   if (argc == 3) {
     fstrm.open(argv[2]);
index 746cf82..ab700fe 100644 (file)
@@ -4,7 +4,6 @@
 // Projects a transduction onto its input or output language.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -18,7 +17,7 @@ int fstproject_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::MutableFstClass;
 
-  string usage =
+  std::string usage =
       "Projects a transduction onto its input"
       " or output language.\n\n  Usage: ";
   usage += argv[0];
@@ -31,8 +30,10 @@ int fstproject_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 7d802ad..2bef035 100644 (file)
@@ -4,7 +4,6 @@
 // Prunes states and arcs of an FST w.r.t. the shortest path weight.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -20,7 +19,7 @@ int fstprune_main(int argc, char **argv) {
   using fst::script::MutableFstClass;
   using fst::script::WeightClass;
 
-  string usage = "Prunes states and arcs of an FST.\n\n  Usage: ";
+  std::string usage = "Prunes states and arcs of an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -31,8 +30,10 @@ int fstprune_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index c70067b..03c5f74 100644 (file)
@@ -5,7 +5,6 @@
 // states.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -25,7 +24,7 @@ int fstpush_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Pushes weights and/or olabels in an FST.\n\n  Usage: ";
+  std::string usage = "Pushes weights and/or olabels in an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -36,8 +35,10 @@ int fstpush_main(int argc, char **argv) {
     return 1;
   }
 
-  string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 7504736..d11665d 100644 (file)
@@ -4,7 +4,6 @@
 // Generates random paths through an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -25,7 +24,7 @@ int fstrandgen_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Generates random paths through an FST.\n\n  Usage: ";
+  std::string usage = "Generates random paths through an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -38,8 +37,10 @@ int fstrandgen_main(int argc, char **argv) {
 
   VLOG(1) << argv[0] << ": Seed = " << FLAGS_seed;
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 41970d7..8dc4ad5 100644 (file)
@@ -4,7 +4,6 @@
 // Relabels input or output space of an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -30,7 +29,7 @@ int fstrelabel_main(int argc, char **argv) {
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
 
-  string usage =
+  std::string usage =
       "Relabels the input and/or the output labels of the FST.\n\n"
       "  Usage: ";
   usage += argv[0];
@@ -49,9 +48,10 @@ int fstrelabel_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 0c4eeb0..02fb92c 100644 (file)
@@ -5,7 +5,6 @@
 // allowing for the definition of FSTs analogous to RTNs.
 
 #include <cstring>
-
 #include <string>
 #include <vector>
 
@@ -31,8 +30,9 @@ int fstreplace_main(int argc, char **argv) {
   using fst::script::VectorFstClass;
   using fst::ReplaceLabelType;
 
-  string usage = "Recursively replaces FST arcs with other FST(s).\n\n"
-                 "  Usage: ";
+  std::string usage =
+      "Recursively replaces FST arcs with other FST(s).\n\n"
+      "  Usage: ";
   usage += argv[0];
   usage += " root.fst rootlabel [rule1.fst label1 ...] [out.fst]\n";
 
@@ -43,8 +43,8 @@ int fstreplace_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = argv[1];
-  const string out_name = argc % 2 == 0 ? argv[argc - 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;
index 86f18c2..e4a7227 100644 (file)
@@ -4,7 +4,6 @@
 // Reverses the paths in an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -19,7 +18,7 @@ int fstreverse_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Reverses the paths in an FST.\n\n  Usage: ";
+  std::string usage = "Reverses the paths in an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -30,9 +29,10 @@ int fstreverse_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 8ca8d84..ad37ff5 100644 (file)
@@ -4,7 +4,6 @@
 // Reweights an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -21,7 +20,7 @@ int fstreweight_main(int argc, char **argv) {
   using fst::script::MutableFstClass;
   using fst::script::WeightClass;
 
-  string usage = "Reweights an FST.\n\n  Usage: ";
+  std::string usage = "Reweights an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " in.fst potential.txt [out.fst]\n";
 
@@ -32,9 +31,9 @@ int fstreweight_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = argv[1];
-  const string potentials_name = argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in_name = argv[1];
+  const std::string potentials_name = argv[2];
+  const std::string out_name = argc > 3 ? argv[3] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index c457d17..24a108e 100644 (file)
@@ -4,7 +4,6 @@
 // Removes epsilons from an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -24,7 +23,7 @@ int fstrmepsilon_main(int argc, char **argv) {
   using fst::script::MutableFstClass;
   using fst::script::WeightClass;
 
-  string usage = "Removes epsilons from an FST.\n\n  Usage: ";
+  std::string usage = "Removes epsilons from an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -35,8 +34,10 @@ int fstrmepsilon_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 1bf2eb3..4bff8e9 100644 (file)
@@ -4,7 +4,6 @@
 // Find shortest distances in an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -27,7 +26,7 @@ int fstshortestdistance_main(int argc, char **argv) {
   using fst::QueueType;
   using fst::AUTO_QUEUE;
 
-  string usage = "Finds shortest distance(s) in an FST.\n\n  Usage: ";
+  std::string usage = "Finds shortest distance(s) in an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [distance.txt]]\n";
 
@@ -38,8 +37,10 @@ int fstshortestdistance_main(int argc, char **argv) {
     return 1;
   }
 
-  string in_name = (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 9becf8f..e63f939 100644 (file)
@@ -4,7 +4,6 @@
 // Find shortest path(s) in an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -27,7 +26,7 @@ int fstshortestpath_main(int argc, char **argv) {
   using fst::script::WeightClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Finds shortest path(s) in an FST.\n\n  Usage: ";
+  std::string usage = "Finds shortest path(s) in an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -38,9 +37,10 @@ int fstshortestpath_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index bf6f974..511d9db 100644 (file)
@@ -5,7 +5,6 @@
 // input FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -33,7 +32,7 @@ int fstsymbols_main(int argc, char **argv) {
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
 
-  string usage =
+  std::string usage =
       "Performs operations (set, clear, relabel) on the symbol"
       " tables attached to an FST.\n\n  Usage: ";
   usage += argv[0];
@@ -46,8 +45,10 @@ int fstsymbols_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = argc > 1 && strcmp(argv[1], "-") != 0 ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      argc > 1 && strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  const std::string out_name =
+      argc > 2 && strcmp(argv[2], "-") != 0 ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index fe23093..a25d654 100644 (file)
@@ -4,7 +4,6 @@
 // Synchronizes an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -16,7 +15,7 @@ int fstsynchronize_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
-  string usage = "Synchronizes an FST.\n\n  Usage: ";
+  std::string usage = "Synchronizes an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -27,8 +26,10 @@ int fstsynchronize_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      (argc > 1 && strcmp(argv[1], "-") != 0) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && strcmp(argv[2], "-") != 0) ? argv[2] : "";
 
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
index 879d5dc..ada55cf 100644 (file)
@@ -4,7 +4,6 @@
 // Topologically sorts an FST.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -16,7 +15,7 @@ int fsttopsort_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::script::MutableFstClass;
 
-  string usage = "Topologically sorts an FST.\n\n  Usage: ";
+  std::string usage = "Topologically sorts an FST.\n\n  Usage: ";
   usage += argv[0];
   usage += " [in.fst [out.fst]]\n";
 
@@ -27,8 +26,10 @@ int fsttopsort_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in_name = argc > 1 && strcmp(argv[1], "-") != 0 ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
+  const std::string in_name =
+      argc > 1 && strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  const std::string out_name =
+      argc > 2 && strcmp(argv[2], "-") != 0 ? argv[2] : "";
 
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
index 995d03e..f42de1e 100644 (file)
@@ -4,7 +4,6 @@
 // Creates the union of two FSTs.
 
 #include <cstring>
-
 #include <memory>
 #include <string>
 
@@ -17,7 +16,7 @@ int fstunion_main(int argc, char **argv) {
   using fst::script::FstClass;
   using fst::script::MutableFstClass;
 
-  string usage = "Creates the union of two FSTs.\n\n  Usage: ";
+  std::string usage = "Creates the union of two FSTs.\n\n  Usage: ";
   usage += argv[0];
   usage += " in1.fst in2.fst [out.fst]\n";
 
@@ -28,9 +27,10 @@ int fstunion_main(int argc, char **argv) {
     return 1;
   }
 
-  const string in1_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
-  const string in2_name = strcmp(argv[2], "-") != 0 ? argv[2] : "";
-  const string out_name = argc > 3 ? argv[3] : "";
+  const std::string in1_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  const std::string in2_name = strcmp(argv[2], "-") != 0 ? argv[2] : "";
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
 
   if (in1_name == "" && in2_name == "") {
     LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input";
index cc28550..7c06a72 100644 (file)
@@ -6,7 +6,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 16:0:0
+libfstcompact_la_LDFLAGS = -version-info 17:0:0
 libfstcompact_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
index bcb292f..d0398b8 100644 (file)
@@ -514,7 +514,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 16:0:0
+libfstcompact_la_LDFLAGS = -version-info 17:0:0
 libfstcompact_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -module
index fa15beb..43b9afb 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 1bb013e..d6aa141 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 95b72c6..99b5209 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 533a0a1..c6c6f33 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 27daceb..e84700c 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 951d0f7..012a12b 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index ab77014..5a039c4 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 366a00f..e37a03f 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index db819db..50c4219 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 001af1b..46fde32 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 7da949e..ff0c998 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index d97d02f..e37cdb9 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 19ce43a..34c4d31 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 72ae73e..91f5658 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index 0c92127..7dba90e 100644 (file)
@@ -1,8 +1,8 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/fst.h>
 #include <fst/compact-fst.h>
+#include <fst/fst.h>
 
 namespace fst {
 
index af715ae..15de88d 100644 (file)
@@ -1,20 +1,19 @@
 AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 
 if HAVE_BIN
-bin_PROGRAMS = fstcompress fstrandmod
+bin_PROGRAMS = fstcompress
 
 LDADD = libfstcompressscript.la \
         ../../script/libfstscript.la \
         ../../lib/libfst.la \
         -lm $(DL_LIBS)
 
-fstcompress_SOURCES = fstcompress.cc
-fstrandmod_SOURCES = fstrandmod.cc
+fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 endif
 
 if HAVE_SCRIPT
-libfstcompressscript_la_SOURCES = compress-script.cc
-libfstcompressscript_la_LDFLAGS = -version-info 16:0:0
+libfstcompressscript_la_SOURCES = compressscript.cc
+libfstcompressscript_la_LDFLAGS = -version-info 17:0:0
 libfstcompressscript_la_LIBADD = \
         ../../script/libfstscript.la \
         ../../lib/libfst.la -lz -lm $(DL_LIBS)
index b5fa35d..376b46a 100644 (file)
@@ -89,7 +89,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-@HAVE_BIN_TRUE@bin_PROGRAMS = fstcompress$(EXEEXT) fstrandmod$(EXEEXT)
+@HAVE_BIN_TRUE@bin_PROGRAMS = fstcompress$(EXEEXT)
 subdir = src/extensions/compress
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
@@ -137,9 +137,9 @@ am__DEPENDENCIES_1 =
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_DEPENDENCIES =  \
 @HAVE_SCRIPT_TRUE@     ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@     ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__libfstcompressscript_la_SOURCES_DIST = compress-script.cc
+am__libfstcompressscript_la_SOURCES_DIST = compressscript.cc
 @HAVE_SCRIPT_TRUE@am_libfstcompressscript_la_OBJECTS =  \
-@HAVE_SCRIPT_TRUE@     compress-script.lo
+@HAVE_SCRIPT_TRUE@     compressscript.lo
 libfstcompressscript_la_OBJECTS =  \
        $(am_libfstcompressscript_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -152,20 +152,14 @@ libfstcompressscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstcompressscript_la_rpath = -rpath $(libdir)
 PROGRAMS = $(bin_PROGRAMS)
-am__fstcompress_SOURCES_DIST = fstcompress.cc
-@HAVE_BIN_TRUE@am_fstcompress_OBJECTS = fstcompress.$(OBJEXT)
+am__fstcompress_SOURCES_DIST = fstcompress.cc fstcompress-main.cc
+@HAVE_BIN_TRUE@am_fstcompress_OBJECTS = fstcompress.$(OBJEXT) \
+@HAVE_BIN_TRUE@        fstcompress-main.$(OBJEXT)
 fstcompress_OBJECTS = $(am_fstcompress_OBJECTS)
 fstcompress_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@fstcompress_DEPENDENCIES = libfstcompressscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__fstrandmod_SOURCES_DIST = fstrandmod.cc
-@HAVE_BIN_TRUE@am_fstrandmod_OBJECTS = fstrandmod.$(OBJEXT)
-fstrandmod_OBJECTS = $(am_fstrandmod_OBJECTS)
-fstrandmod_LDADD = $(LDADD)
-@HAVE_BIN_TRUE@fstrandmod_DEPENDENCIES = libfstcompressscript.la \
-@HAVE_BIN_TRUE@        ../../script/libfstscript.la \
-@HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -200,10 +194,9 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
 am__v_CXXLD_1 = 
-SOURCES = $(libfstcompressscript_la_SOURCES) $(fstcompress_SOURCES) \
-       $(fstrandmod_SOURCES)
+SOURCES = $(libfstcompressscript_la_SOURCES) $(fstcompress_SOURCES)
 DIST_SOURCES = $(am__libfstcompressscript_la_SOURCES_DIST) \
-       $(am__fstcompress_SOURCES_DIST) $(am__fstrandmod_SOURCES_DIST)
+       $(am__fstcompress_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -373,10 +366,9 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@        ../../lib/libfst.la \
 @HAVE_BIN_TRUE@        -lm $(DL_LIBS)
 
-@HAVE_BIN_TRUE@fstcompress_SOURCES = fstcompress.cc
-@HAVE_BIN_TRUE@fstrandmod_SOURCES = fstrandmod.cc
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_SOURCES = compress-script.cc
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 16:0:0
+@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 17:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = \
 @HAVE_SCRIPT_TRUE@        ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lz -lm $(DL_LIBS)
@@ -507,19 +499,15 @@ fstcompress$(EXEEXT): $(fstcompress_OBJECTS) $(fstcompress_DEPENDENCIES) $(EXTRA
        @rm -f fstcompress$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(fstcompress_OBJECTS) $(fstcompress_LDADD) $(LIBS)
 
-fstrandmod$(EXEEXT): $(fstrandmod_OBJECTS) $(fstrandmod_DEPENDENCIES) $(EXTRA_fstrandmod_DEPENDENCIES) 
-       @rm -f fstrandmod$(EXEEXT)
-       $(AM_V_CXXLD)$(CXXLINK) $(fstrandmod_OBJECTS) $(fstrandmod_LDADD) $(LIBS)
-
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
 
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress-script.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressscript.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstcompress.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrandmod.Po@am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
similarity index 58%
rename from src/extensions/compress/compress-script.cc
rename to src/extensions/compress/compressscript.cc
index 85225a4..0b4a6c3 100644 (file)
@@ -1,13 +1,7 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
-//
-// Definitions of 'scriptable' versions of compression operations, that is,
-// those that can be called with FstClass-type arguments.
-//
-// See comments in nlp/fst/script/script-impl.h for how the registration
-// mechanism allows these to work with various arc types.
 
-#include <fst/extensions/compress/compress-script.h>
+#include <fst/extensions/compress/compressscript.h>
 
 #include <fst/arc-map.h>
 #include <fst/script/script-impl.h>
 namespace fst {
 namespace script {
 
-void Compress(const FstClass &fst, const string &filename, const bool gzip) {
-  CompressArgs args(fst, filename, gzip);
+bool Compress(const FstClass &fst, const std::string &filename,
+              const bool gzip) {
+  CompressInnerArgs iargs(fst, filename, gzip);
+  CompressArgs args(iargs);
   Apply<Operation<CompressArgs>>("Compress", fst.ArcType(), &args);
+  return args.retval;
 }
 
-void Decompress(const string &filename, MutableFstClass *fst, const bool gzip) {
-  DecompressArgs args(filename, fst, gzip);
+bool Decompress(const std::string &filename, MutableFstClass *fst,
+                const bool gzip) {
+  DecompressInnerArgs iargs(filename, fst, gzip);
+  DecompressArgs args(iargs);
   Apply<Operation<DecompressArgs>>("Decompress", fst->ArcType(), &args);
+  return args.retval;
 }
 
 // Register operations for common arc types.
diff --git a/src/extensions/compress/fstcompress-main.cc b/src/extensions/compress/fstcompress-main.cc
new file mode 100644 (file)
index 0000000..cb4caf3
--- /dev/null
@@ -0,0 +1,58 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Compresses/decompresses an FST.
+
+#include <cstring>
+#include <memory>
+#include <string>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/compress/compressscript.h>
+#include <fst/script/arg-packs.h>
+#include <fst/script/fst-class.h>
+
+DECLARE_string(arc_type);
+DECLARE_bool(decode);
+DECLARE_bool(gzip);
+
+int fstcompress_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+
+  std::string usage = "Compresses/decompresses an FST.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " [in.fst [out.fstz]]\n";
+  usage += " --decode [in.fstz [out.fst]]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  if (FLAGS_decode) {
+    VectorFstClass fst(FLAGS_arc_type);
+    if (!s::Decompress(in_name, &fst, FLAGS_gzip)) {
+      FSTERROR() << "Decompression failed";
+      return 1;
+    }
+    return !fst.Write(out_name);
+  } else {
+    std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+    if (!ifst) return 1;
+    if (!s::Compress(*ifst, out_name, FLAGS_gzip)) {
+      FSTERROR() << "Compression failed";
+      return 1;
+    }
+    return 0;
+  }
+}
index 38d3209..17b16b5 100644 (file)
@@ -1,55 +1,15 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
-//
-// Compresses/decompresses an FST.
-
-#include <cstring>
-#include <memory>
-#include <string>
 
 #include <fst/flags.h>
-#include <fst/log.h>
-#include <fst/extensions/compress/compress-script.h>
-#include <fst/script/arg-packs.h>
-#include <fst/script/fst-class.h>
 
 DEFINE_string(arc_type, "standard", "Output arc type");
 DEFINE_bool(decode, false, "Decode");
 DEFINE_bool(gzip, false,
             "Applies gzip compression after LZA compression and "
-            "gzip decompression before LZA decompression "
-            "(recommended)"
-            "");
-
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  using s::FstClass;
-  using s::VectorFstClass;
-
-  string usage = "Compresses/decompresses an FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " [in.fst [out.fstz]]\n";
-  usage += " --decode [in.fstz [out.fst]]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
+            "gzip decompression before LZA decompression"
+);
 
-  string in_name = (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  string out_name = argc > 2 ? argv[2] : "";
+int fstcompress_main(int argc, char **argv);
 
-  if (FLAGS_decode == false) {
-    std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-    if (!ifst) return 1;
-    s::Compress(*ifst, out_name, FLAGS_gzip);
-  } else {
-    VectorFstClass ofst(FLAGS_arc_type);
-    s::Decompress(in_name, &ofst, FLAGS_gzip);
-    ofst.Write(out_name);
-  }
-  return 0;
-}
+int main(int argc, char **argv) { return fstcompress_main(argc, argv); }
diff --git a/src/extensions/compress/fstrandmod.cc b/src/extensions/compress/fstrandmod.cc
deleted file mode 100644 (file)
index 17f5ba0..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Generates a random FST according to a class-specific transition model.
-
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <memory>
-#include <string>
-
-#include <fst/flags.h>
-#include <fst/log.h>
-#include <fst/extensions/compress/randmod.h>
-#include <fst/fstlib.h>
-
-DEFINE_int32(seed, time(0), "Random seed");
-DEFINE_int32(states, 10, "# of states");
-DEFINE_int32(labels, 2, "# of labels");
-DEFINE_int32(classes, 1, "# of probability distributions");
-DEFINE_bool(transducer, false, "Output a transducer");
-DEFINE_bool(weights, false, "Output a weighted FST");
-
-int main(int argc, char **argv) {
-  using fst::StdVectorFst;
-  using fst::StdArc;
-  using fst::TropicalWeight;
-  using fst::WeightGenerate;
-
-  string usage = "Generates a random FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += "[out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 2) {
-    ShowUsage();
-    return 1;
-  }
-
-  string out_name = (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-
-  srand(FLAGS_seed);
-
-  int num_states = (rand() % FLAGS_states) + 1;    // NOLINT
-  int num_classes = (rand() % FLAGS_classes) + 1;  // NOLINT
-  int num_labels = (rand() % FLAGS_labels) + 1;    // NOLINT
-
-  StdVectorFst fst;
-  using TropicalWeightGenerate = WeightGenerate<TropicalWeight>;
-  std::unique_ptr<TropicalWeightGenerate> generate(FLAGS_weights ?
-      new TropicalWeightGenerate(false) : nullptr);
-  fst::RandMod<StdArc, TropicalWeightGenerate> rand_mod(num_states,
-      num_classes, num_labels, FLAGS_transducer, generate.get());
-  rand_mod.Generate(&fst);
-  fst.Write(out_name);
-  return 0;
-}
index 4ad7ab0..aa0dbad 100644 (file)
@@ -6,7 +6,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 16:0:0 -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 libfstconst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 const8_fst_la_SOURCES = const8-fst.cc
index 21e369f..fc46091 100644 (file)
@@ -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 16:0:0 -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 libfstconst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -module
index 7a7c985..a97fa0f 100644 (file)
@@ -7,13 +7,13 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 16:0:0
+libfstfar_la_LDFLAGS = -version-info 17: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
-libfstfarscript_la_LDFLAGS = -version-info 16:0:0
+libfstfarscript_la_LDFLAGS = -version-info 17:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
@@ -26,17 +26,17 @@ bin_PROGRAMS = farcompilestrings farcreate farequal farextract farinfo \
 LDADD = libfstfarscript.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
 
-farcompilestrings_SOURCES = farcompilestrings.cc
+farcompilestrings_SOURCES = farcompilestrings.cc farcompilestrings-main.cc
 
-farcreate_SOURCES = farcreate.cc
+farcreate_SOURCES = farcreate.cc farcreate-main.cc
 
-farequal_SOURCES = farequal.cc
+farequal_SOURCES = farequal.cc farequal-main.cc
 
-farextract_SOURCES = farextract.cc
+farextract_SOURCES = farextract.cc farextract-main.cc
 
-farinfo_SOURCES = farinfo.cc
+farinfo_SOURCES = farinfo.cc farinfo-main.cc
 
-farisomorphic_SOURCES = farisomorphic.cc
+farisomorphic_SOURCES = farisomorphic.cc farisomorphic-main.cc
 
-farprintstrings_SOURCES = farprintstrings.cc
+farprintstrings_SOURCES = farprintstrings.cc farprintstrings-main.cc
 endif
index 4e1623c..36a97da 100644 (file)
@@ -164,51 +164,61 @@ libfstfarscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstfarscript_la_rpath = -rpath $(libdir)
 PROGRAMS = $(bin_PROGRAMS)
-am__farcompilestrings_SOURCES_DIST = farcompilestrings.cc
+am__farcompilestrings_SOURCES_DIST = farcompilestrings.cc \
+       farcompilestrings-main.cc
 @HAVE_BIN_TRUE@am_farcompilestrings_OBJECTS =  \
-@HAVE_BIN_TRUE@        farcompilestrings.$(OBJEXT)
+@HAVE_BIN_TRUE@        farcompilestrings.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farcompilestrings-main.$(OBJEXT)
 farcompilestrings_OBJECTS = $(am_farcompilestrings_OBJECTS)
 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__farcreate_SOURCES_DIST = farcreate.cc
-@HAVE_BIN_TRUE@am_farcreate_OBJECTS = farcreate.$(OBJEXT)
+am__farcreate_SOURCES_DIST = farcreate.cc farcreate-main.cc
+@HAVE_BIN_TRUE@am_farcreate_OBJECTS = farcreate.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farcreate-main.$(OBJEXT)
 farcreate_OBJECTS = $(am_farcreate_OBJECTS)
 farcreate_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farcreate_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__farequal_SOURCES_DIST = farequal.cc
-@HAVE_BIN_TRUE@am_farequal_OBJECTS = farequal.$(OBJEXT)
+am__farequal_SOURCES_DIST = farequal.cc farequal-main.cc
+@HAVE_BIN_TRUE@am_farequal_OBJECTS = farequal.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farequal-main.$(OBJEXT)
 farequal_OBJECTS = $(am_farequal_OBJECTS)
 farequal_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farequal_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__farextract_SOURCES_DIST = farextract.cc
-@HAVE_BIN_TRUE@am_farextract_OBJECTS = farextract.$(OBJEXT)
+am__farextract_SOURCES_DIST = farextract.cc farextract-main.cc
+@HAVE_BIN_TRUE@am_farextract_OBJECTS = farextract.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farextract-main.$(OBJEXT)
 farextract_OBJECTS = $(am_farextract_OBJECTS)
 farextract_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farextract_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__farinfo_SOURCES_DIST = farinfo.cc
-@HAVE_BIN_TRUE@am_farinfo_OBJECTS = farinfo.$(OBJEXT)
+am__farinfo_SOURCES_DIST = farinfo.cc farinfo-main.cc
+@HAVE_BIN_TRUE@am_farinfo_OBJECTS = farinfo.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farinfo-main.$(OBJEXT)
 farinfo_OBJECTS = $(am_farinfo_OBJECTS)
 farinfo_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farinfo_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__farisomorphic_SOURCES_DIST = farisomorphic.cc
-@HAVE_BIN_TRUE@am_farisomorphic_OBJECTS = farisomorphic.$(OBJEXT)
+am__farisomorphic_SOURCES_DIST = farisomorphic.cc \
+       farisomorphic-main.cc
+@HAVE_BIN_TRUE@am_farisomorphic_OBJECTS = farisomorphic.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farisomorphic-main.$(OBJEXT)
 farisomorphic_OBJECTS = $(am_farisomorphic_OBJECTS)
 farisomorphic_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farisomorphic_DEPENDENCIES = libfstfarscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__farprintstrings_SOURCES_DIST = farprintstrings.cc
-@HAVE_BIN_TRUE@am_farprintstrings_OBJECTS = farprintstrings.$(OBJEXT)
+am__farprintstrings_SOURCES_DIST = farprintstrings.cc \
+       farprintstrings-main.cc
+@HAVE_BIN_TRUE@am_farprintstrings_OBJECTS = farprintstrings.$(OBJEXT) \
+@HAVE_BIN_TRUE@        farprintstrings-main.$(OBJEXT)
 farprintstrings_OBJECTS = $(am_farprintstrings_OBJECTS)
 farprintstrings_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@farprintstrings_DEPENDENCIES = libfstfarscript.la \
@@ -426,12 +436,12 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @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 16:0:0
+libfstfar_la_LDFLAGS = -version-info 17: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
 
-@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 16:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 17: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)
@@ -439,13 +449,13 @@ libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 @HAVE_BIN_TRUE@LDADD = libfstfarscript.la ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
 
-@HAVE_BIN_TRUE@farcompilestrings_SOURCES = farcompilestrings.cc
-@HAVE_BIN_TRUE@farcreate_SOURCES = farcreate.cc
-@HAVE_BIN_TRUE@farequal_SOURCES = farequal.cc
-@HAVE_BIN_TRUE@farextract_SOURCES = farextract.cc
-@HAVE_BIN_TRUE@farinfo_SOURCES = farinfo.cc
-@HAVE_BIN_TRUE@farisomorphic_SOURCES = farisomorphic.cc
-@HAVE_BIN_TRUE@farprintstrings_SOURCES = farprintstrings.cc
+@HAVE_BIN_TRUE@farcompilestrings_SOURCES = farcompilestrings.cc farcompilestrings-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
+@HAVE_BIN_TRUE@farinfo_SOURCES = farinfo.cc farinfo-main.cc
+@HAVE_BIN_TRUE@farisomorphic_SOURCES = farisomorphic.cc farisomorphic-main.cc
+@HAVE_BIN_TRUE@farprintstrings_SOURCES = farprintstrings.cc farprintstrings-main.cc
 all: all-am
 
 .SUFFIXES:
@@ -605,12 +615,19 @@ distclean-compile:
        -rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/far-class.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcompilestrings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farcreate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farequal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farextract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farisomorphic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farprintstrings.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farscript.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@
index e6ac495..e41a196 100644 (file)
@@ -12,12 +12,13 @@ namespace script {
 
 // FarReaderClass.
 
-FarReaderClass *FarReaderClass::Open(const string &filename) {
-  const std::vector<string> filenames{filename};
+FarReaderClass *FarReaderClass::Open(const std::string &filename) {
+  const std::vector<std::string> filenames{filename};
   return FarReaderClass::Open(filenames);
 }
 
-FarReaderClass *FarReaderClass::Open(const std::vector<string> &filenames) {
+FarReaderClass *FarReaderClass::Open(
+    const std::vector<std::string> &filenames) {
   if (filenames.empty()) {
     LOG(ERROR) << "FarReaderClass::Open: No files specified";
     return nullptr;
@@ -37,8 +38,9 @@ REGISTER_FST_OPERATION(OpenFarReaderClass, Log64Arc, OpenFarReaderClassArgs);
 
 // FarWriterClass.
 
-FarWriterClass *FarWriterClass::Create(const string &filename,
-                                       const string &arc_type, FarType type) {
+FarWriterClass *FarWriterClass::Create(const std::string &filename,
+                                       const std::string &arc_type,
+                                       FarType type) {
   CreateFarWriterClassInnerArgs iargs(filename, type);
   CreateFarWriterClassArgs args(iargs);
   args.retval = nullptr;
diff --git a/src/extensions/far/farcompilestrings-main.cc b/src/extensions/far/farcompilestrings-main.cc
new file mode 100644 (file)
index 0000000..da47097
--- /dev/null
@@ -0,0 +1,85 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Compiles a set of stings as FSTs and stores them in a finite-state archive.
+
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+#include <fstream>
+
+DECLARE_string(key_prefix);
+DECLARE_string(key_suffix);
+DECLARE_int32(generate_keys);
+DECLARE_string(far_type);
+DECLARE_bool(allow_negative_labels);
+DECLARE_string(arc_type);
+DECLARE_string(entry_type);
+DECLARE_string(fst_type);
+DECLARE_string(token_type);
+DECLARE_string(symbols);
+DECLARE_string(unknown_symbol);
+DECLARE_bool(file_list_input);
+DECLARE_bool(keep_symbols);
+DECLARE_bool(initial_symbols);
+
+int farcompilestrings_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage = "Compiles a set of strings as FSTs and stores them in";
+  usage += " a finite-state archive.\n\n  Usage:";
+  usage += argv[0];
+  usage += " [in1.txt [[in2.txt ...] out.far]]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  std::vector<std::string> in_fnames;
+  if (FLAGS_file_list_input) {
+    for (int i = 1; i < argc - 1; ++i) {
+      std::ifstream istrm(argv[i]);
+      std::string str;
+      while (getline(istrm, str)) in_fnames.push_back(str);
+    }
+  } else {
+    for (int i = 1; i < argc - 1; ++i)
+      in_fnames.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
+  }
+  if (in_fnames.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_fnames.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_fname =
+      argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
+
+  fst::FarEntryType entry_type;
+  if (!s::GetFarEntryType(FLAGS_entry_type, &entry_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR entry type: " << FLAGS_entry_type;
+    return 1;
+  }
+
+  fst::FarTokenType token_type;
+  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
+    LOG(ERROR) << "Unkonwn or unsupported FAR token type: " << FLAGS_token_type;
+    return 1;
+  }
+
+  const auto far_type = s::GetFarType(FLAGS_far_type);
+
+  s::FarCompileStrings(in_fnames, out_fname, FLAGS_arc_type, FLAGS_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,
+                       FLAGS_key_prefix, FLAGS_key_suffix);
+
+  return 0;
+}
index d510f17..e1844f3 100644 (file)
@@ -1,15 +1,4 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Compiles a set of stings as FSTs and stores them in a finite-state archive.
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
-#include <fstream>
 
 DEFINE_string(key_prefix, "", "Prefix to append to keys");
 DEFINE_string(key_suffix, "", "Suffix to append to keys");
@@ -28,7 +17,8 @@ DEFINE_string(fst_type, "vector", "Output FST type");
 DEFINE_string(token_type, "symbol",
               "Token type: one of : "
               "\"symbol\", \"byte\", \"utf8\"");
-DEFINE_string(symbols, "", "Label symbol table");
+DEFINE_string(symbols, "",
+              "Label symbol table. Only applies to \"symbol\" tokens.");
 DEFINE_string(unknown_symbol, "", "");
 DEFINE_bool(file_list_input, false,
             "Each input file contains a list of files to be processed");
@@ -37,55 +27,7 @@ DEFINE_bool(initial_symbols, true,
             "When keep_symbols is true, stores symbol table only for the first"
             " FST in archive.");
 
+int farcompilestrings_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Compiles a set of strings as FSTs and stores them in";
-  usage += " a finite-state archive.\n\n  Usage:";
-  usage += argv[0];
-  usage += " [in1.txt [[in2.txt ...] out.far]]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  std::vector<string> in_fnames;
-  if (FLAGS_file_list_input) {
-    for (int i = 1; i < argc - 1; ++i) {
-      std::ifstream istrm(argv[i]);
-      string str;
-      while (getline(istrm, str)) in_fnames.push_back(str);
-    }
-  } else {
-    for (int i = 1; i < argc - 1; ++i)
-      in_fnames.push_back(argv[i]);
-  }
-  if (in_fnames.empty()) {
-    in_fnames.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
-  }
-
-  string out_fname =
-      argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
-
-  fst::FarEntryType entry_type;
-  if (!s::GetFarEntryType(FLAGS_entry_type, &entry_type)) {
-    LOG(ERROR) << "Unknown or unsupported FAR entry type: " << FLAGS_entry_type;
-    return 1;
-  }
-
-  fst::FarTokenType token_type;
-  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
-    LOG(ERROR) << "Unkonwn or unsupported FAR token type: " << FLAGS_token_type;
-    return 1;
-  }
-
-  const auto far_type = s::GetFarType(FLAGS_far_type);
-
-  s::FarCompileStrings(in_fnames, out_fname, FLAGS_arc_type, FLAGS_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,
-                       FLAGS_key_prefix, FLAGS_key_suffix);
-
-  return 0;
+  return farcompilestrings_main(argc, argv);
 }
diff --git a/src/extensions/far/farcreate-main.cc b/src/extensions/far/farcreate-main.cc
new file mode 100644 (file)
index 0000000..493abbd
--- /dev/null
@@ -0,0 +1,64 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Creates a finite-state archive from input FSTs.
+
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+#include <fstream>
+
+DECLARE_string(key_prefix);
+DECLARE_string(key_suffix);
+DECLARE_int32(generate_keys);
+DECLARE_string(far_type);
+DECLARE_bool(file_list_input);
+
+int farcreate_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage =
+      "Creates a finite-state archive from input FSTs.\n\n Usage:";
+  usage += argv[0];
+  usage += " [in1.fst [[in2.fst ...] out.far]]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  std::vector<std::string> in_fnames;
+  if (FLAGS_file_list_input) {
+    for (int i = 1; i < argc - 1; ++i) {
+      std::ifstream istrm(argv[i]);
+      std::string str;
+      while (getline(istrm, str)) in_fnames.push_back(str);
+    }
+  } else {
+    for (int i = 1; i < argc - 1; ++i)
+      in_fnames.push_back(strcmp(argv[i], "-") != 0 ? argv[i] : "");
+  }
+  if (in_fnames.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_fnames.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_fname =
+      argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
+
+  const auto arc_type = s::LoadArcTypeFromFst(in_fnames[0]);
+  if (arc_type.empty()) return 1;
+
+  const auto far_type = s::GetFarType(FLAGS_far_type);
+
+  s::FarCreate(in_fnames, out_fname, arc_type, FLAGS_generate_keys, far_type,
+               FLAGS_key_prefix, FLAGS_key_suffix);
+
+  return 0;
+}
index 1f26c64..1d04be3 100644 (file)
@@ -1,15 +1,4 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Creates a finite-state archive from input FSTs.
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
-#include <fstream>
 
 DEFINE_string(key_prefix, "", "Prefix to append to keys");
 DEFINE_string(key_suffix, "", "Suffix to append to keys");
@@ -21,41 +10,7 @@ DEFINE_string(far_type, "default",
 DEFINE_bool(file_list_input, false,
             "Each input file contains a list of files to be processed");
 
+int farcreate_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Creates a finite-state archive from input FSTs.\n\n Usage:";
-  usage += argv[0];
-  usage += " [in1.fst [[in2.fst ...] out.far]]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  std::vector<string> in_fnames;
-  if (FLAGS_file_list_input) {
-    for (int i = 1; i < argc - 1; ++i) {
-      std::ifstream istrm(argv[i]);
-      string str;
-      while (getline(istrm, str)) in_fnames.push_back(str);
-    }
-  } else {
-    for (int i = 1; i < argc - 1; ++i)
-      in_fnames.push_back(argv[i]);
-  }
-  if (in_fnames.empty())
-    in_fnames.push_back(argc == 2 && strcmp(argv[1], "-") != 0 ? argv[1] : "");
-
-  string out_fname =
-      argc > 2 && strcmp(argv[argc - 1], "-") != 0 ? argv[argc - 1] : "";
-
-  const auto arc_type = s::LoadArcTypeFromFst(in_fnames[0]);
-  if (arc_type.empty()) return 1;
-
-  const auto far_type = s::GetFarType(FLAGS_far_type);
-
-  s::FarCreate(in_fnames, out_fname, arc_type, FLAGS_generate_keys, far_type,
-               FLAGS_key_prefix, FLAGS_key_suffix);
-
-  return 0;
+  return farcreate_main(argc, argv);
 }
diff --git a/src/extensions/far/farequal-main.cc b/src/extensions/far/farequal-main.cc
new file mode 100644 (file)
index 0000000..6e49da8
--- /dev/null
@@ -0,0 +1,41 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Tests if two Far files contains the same (key,fst) pairs.
+
+#include <string>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(begin_key);
+DECLARE_string(end_key);
+DECLARE_double(delta);
+
+int farequal_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage = "Compares the FSTs in two FST archives for equality.";
+  usage += "\n\n  Usage:";
+  usage += argv[0];
+  usage += " in1.far in2.far";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+  if (argc != 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const auto arc_type = s::LoadArcTypeFromFar(argv[1]);
+  if (arc_type.empty()) return 1;
+
+  bool result = s::FarEqual(argv[1], argv[2], arc_type, FLAGS_delta,
+                            FLAGS_begin_key, FLAGS_end_key);
+
+  if (!result) VLOG(1) << "FARs are not equal.";
+
+  return result ? 0 : 2;
+}
index 8b98faa..4890f87 100644 (file)
@@ -1,42 +1,12 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Tests if two Far files contains the same (key,fst) pairs.
-
-#include <string>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
+#include <fst/weight.h>
 
 DEFINE_string(begin_key, "",
               "First key to extract (def: first key in archive)");
 DEFINE_string(end_key, "", "Last key to extract (def: last key in archive)");
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
+int farequal_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Compares the FSTs in two FST archives for equality.";
-  usage += "\n\n  Usage:";
-  usage += argv[0];
-  usage += " in1.far in2.far";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-  if (argc != 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const auto arc_type = s::LoadArcTypeFromFar(argv[1]);
-  if (arc_type.empty()) return 1;
-
-  bool result = s::FarEqual(argv[1], argv[2], arc_type, FLAGS_delta,
-                            FLAGS_begin_key, FLAGS_end_key);
-
-  if (!result) VLOG(1) << "FARs are not equal.";
-
-  return result ? 0 : 2;
+  return farequal_main(argc, argv);
 }
diff --git a/src/extensions/far/farextract-main.cc b/src/extensions/far/farextract-main.cc
new file mode 100644 (file)
index 0000000..78e6a06
--- /dev/null
@@ -0,0 +1,43 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Extracts component FSTs from an finite-state archive.
+
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(filename_prefix);
+DECLARE_string(filename_suffix);
+DECLARE_int32(generate_filenames);
+DECLARE_string(keys);
+DECLARE_string(key_separator);
+DECLARE_string(range_delimiter);
+
+int farextract_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage = "Extracts FSTs from a finite-state archive.\n\n Usage:";
+  usage += argv[0];
+  usage += " [in1.far in2.far...]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  std::vector<std::string> in_fnames;
+  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
+  if (in_fnames.empty()) in_fnames.push_back("");
+
+  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  if (arc_type.empty()) return 1;
+
+  s::FarExtract(in_fnames, arc_type, FLAGS_generate_filenames, FLAGS_keys,
+                FLAGS_key_separator, FLAGS_range_delimiter,
+                FLAGS_filename_prefix, FLAGS_filename_suffix);
+
+  return 0;
+}
index df40bd4..b31d51a 100644 (file)
@@ -1,14 +1,4 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Extracts component FSTs from an finite-state archive.
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
 
 DEFINE_string(filename_prefix, "", "Prefix to append to filenames");
 DEFINE_string(filename_suffix, "", "Suffix to append to filenames");
@@ -20,27 +10,7 @@ DEFINE_string(keys, "",
 DEFINE_string(key_separator, ",", "Separator for individual keys");
 DEFINE_string(range_delimiter, "-", "Delimiter for ranges of keys");
 
+int farextract_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Extracts FSTs from a finite-state archive.\n\n Usage:";
-  usage += argv[0];
-  usage += " [in1.far in2.far...]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  std::vector<string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
-
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
-  if (arc_type.empty()) return 1;
-
-  s::FarExtract(in_fnames, arc_type, FLAGS_generate_filenames, FLAGS_keys,
-                FLAGS_key_separator, FLAGS_range_delimiter,
-                FLAGS_filename_prefix, FLAGS_filename_suffix);
-
-  return 0;
+  return farextract_main(argc, argv);
 }
diff --git a/src/extensions/far/farinfo-main.cc b/src/extensions/far/farinfo-main.cc
new file mode 100644 (file)
index 0000000..687a0cf
--- /dev/null
@@ -0,0 +1,41 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Prints some basic information about the FSTs in an FST archive.
+
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(begin_key);
+DECLARE_string(end_key);
+DECLARE_bool(list_fsts);
+
+int farinfo_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage = "Prints some basic information about the FSTs in an FST ";
+  usage += "archive.\n\n  Usage:";
+  usage += argv[0];
+  usage += " [in1.far in2.far...]\n";
+  usage += "  Flags: begin_key end_key list_fsts";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  std::vector<std::string> in_fnames;
+  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
+  if (in_fnames.empty()) in_fnames.push_back("");
+
+  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  if (arc_type.empty()) return 1;
+
+  s::FarInfo(in_fnames, arc_type, FLAGS_begin_key, FLAGS_end_key,
+             FLAGS_list_fsts);
+
+  return 0;
+}
index f004d3e..3029685 100644 (file)
@@ -1,14 +1,4 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Prints some basic information about the FSTs in an FST archive.
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
 
 DEFINE_string(begin_key, "",
               "First key to extract (default: first key in archive)");
@@ -17,28 +7,7 @@ DEFINE_string(end_key, "",
 
 DEFINE_bool(list_fsts, false, "Display FST information for each key");
 
+int farinfo_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Prints some basic information about the FSTs in an FST ";
-  usage += "archive.\n\n  Usage:";
-  usage += argv[0];
-  usage += " [in1.far in2.far...]\n";
-  usage += "  Flags: begin_key end_key list_fsts";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  std::vector<string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
-
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
-  if (arc_type.empty()) return 1;
-
-  s::FarInfo(in_fnames, arc_type, FLAGS_begin_key, FLAGS_end_key,
-             FLAGS_list_fsts);
-
-  return 0;
+  return farinfo_main(argc, argv);
 }
diff --git a/src/extensions/far/farisomorphic-main.cc b/src/extensions/far/farisomorphic-main.cc
new file mode 100644 (file)
index 0000000..cb0a6bf
--- /dev/null
@@ -0,0 +1,43 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Tests if two Far files contains isomorphic (key,fst) pairs.
+
+#include <string>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(begin_key);
+DECLARE_string(end_key);
+DECLARE_double(delta);
+
+int farisomorphic_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage = "Compares the FSTs in two FST archives for isomorphism.";
+  usage += "\n\n  Usage:";
+  usage += argv[0];
+  usage += " in1.far in2.far\n";
+  usage += "  Flags: begin_key end_key";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  if (argc != 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const auto arc_type = s::LoadArcTypeFromFar(argv[1]);
+  if (arc_type.empty()) return 1;
+
+  bool result = s::FarIsomorphic(argv[1], argv[2], arc_type,
+                                 FLAGS_delta, FLAGS_begin_key, FLAGS_end_key);
+
+  if (!result) VLOG(1) << "FARs are not isomorphic.";
+
+  return result ? 0 : 2;
+}
index 6efda1d..1ca9263 100644 (file)
@@ -1,44 +1,12 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Tests if two Far files contains isomorphic (key,fst) pairs.
-
-#include <string>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
+#include <fst/weight.h>
 
 DEFINE_string(begin_key, "",
               "First key to extract (def: first key in archive)");
 DEFINE_string(end_key, "", "Last key to extract (def: last key in archive)");
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
+int farisomorphic_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Compares the FSTs in two FST archives for isomorphism.";
-  usage += "\n\n  Usage:";
-  usage += argv[0];
-  usage += " in1.far in2.far\n";
-  usage += "  Flags: begin_key end_key";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  if (argc != 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const auto arc_type = s::LoadArcTypeFromFar(argv[1]);
-  if (arc_type.empty()) return 1;
-
-  bool result = s::FarIsomorphic(argv[1], argv[2], arc_type,
-                                 FLAGS_delta, FLAGS_begin_key, FLAGS_end_key);
-
-  if (!result) VLOG(1) << "FARs are not isomorphic.";
-
-  return result ? 0 : 2;
+  return farisomorphic_main(argc, argv);
 }
diff --git a/src/extensions/far/farprintstrings-main.cc b/src/extensions/far/farprintstrings-main.cc
new file mode 100644 (file)
index 0000000..6c1d9f4
--- /dev/null
@@ -0,0 +1,63 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Outputs as strings the string FSTs in a finite-state archive.
+
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/far/farscript.h>
+#include <fst/extensions/far/getters.h>
+
+DECLARE_string(filename_prefix);
+DECLARE_string(filename_suffix);
+DECLARE_int32(generate_filenames);
+DECLARE_string(begin_key);
+DECLARE_string(end_key);
+DECLARE_bool(print_key);
+DECLARE_bool(print_weight);
+DECLARE_string(entry_type);
+DECLARE_string(token_type);
+DECLARE_string(symbols);
+DECLARE_bool(initial_symbols);
+
+int farprintstrings_main(int argc, char **argv) {
+  namespace s = fst::script;
+
+  std::string usage =
+      "Print as std::string the std::string FSTs in an archive.\n\n  Usage:";
+  usage += argv[0];
+  usage += " [in1.far in2.far ...]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  s::ExpandArgs(argc, argv, &argc, &argv);
+
+  std::vector<std::string> in_fnames;
+  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
+  if (in_fnames.empty()) in_fnames.push_back("");
+
+  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
+  if (arc_type.empty()) return 1;
+
+  fst::FarEntryType entry_type;
+  if (!s::GetFarEntryType(FLAGS_entry_type, &entry_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR entry type: " << FLAGS_entry_type;
+    return 1;
+  }
+
+  fst::FarTokenType token_type;
+  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR token type: " << FLAGS_token_type;
+    return 1;
+  }
+
+  s::FarPrintStrings(in_fnames, arc_type, entry_type, token_type,
+                     FLAGS_begin_key, FLAGS_end_key, FLAGS_print_key,
+                     FLAGS_print_weight, FLAGS_symbols, FLAGS_initial_symbols,
+                     FLAGS_generate_filenames, FLAGS_filename_prefix,
+                     FLAGS_filename_suffix);
+
+  return 0;
+}
index bcd5d45..05f42e8 100644 (file)
@@ -1,14 +1,4 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Outputs as strings the string FSTs in a finite-state archive.
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
 
 DEFINE_string(filename_prefix, "", "Prefix to append to filenames");
 DEFINE_string(filename_suffix, "", "Suffix to append to filenames");
@@ -18,8 +8,8 @@ DEFINE_string(begin_key, "",
               "First key to extract (def: first key in archive)");
 DEFINE_string(end_key, "", "Last key to extract (def: last key in archive)");
 // PrintStringsMain specific flag definitions.
-DEFINE_bool(print_key, false, "Prefix each string by its key");
-DEFINE_bool(print_weight, false, "Suffix each string by its weight");
+DEFINE_bool(print_key, false, "Prefix each std::string by its key");
+DEFINE_bool(print_weight, false, "Suffix each std::string by its weight");
 DEFINE_string(entry_type, "line",
               "Entry type: one of : "
               "\"file\" (one FST per file), \"line\" (one FST per line)");
@@ -30,41 +20,7 @@ DEFINE_string(symbols, "", "Label symbol table");
 DEFINE_bool(initial_symbols, true,
             "Uses symbol table from the first Fst in archive for all entries.");
 
+int farprintstrings_main(int argc, char **argv);
 int main(int argc, char **argv) {
-  namespace s = fst::script;
-
-  string usage = "Print as string the string FSTs in an archive.\n\n  Usage:";
-  usage += argv[0];
-  usage += " [in1.far in2.far ...]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  s::ExpandArgs(argc, argv, &argc, &argv);
-
-  std::vector<string> in_fnames;
-  for (int i = 1; i < argc; ++i) in_fnames.push_back(argv[i]);
-  if (in_fnames.empty()) in_fnames.push_back("");
-
-  const auto arc_type = s::LoadArcTypeFromFar(in_fnames[0]);
-  if (arc_type.empty()) return 1;
-
-  fst::FarEntryType entry_type;
-  if (!s::GetFarEntryType(FLAGS_entry_type, &entry_type)) {
-    LOG(ERROR) << "Unknown or unsupported FAR entry type: " << FLAGS_entry_type;
-    return 1;
-  }
-
-  fst::FarTokenType token_type;
-  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
-    LOG(ERROR) << "Unknown or unsupported FAR token type: " << FLAGS_token_type;
-    return 1;
-  }
-
-  s::FarPrintStrings(in_fnames, arc_type, entry_type, token_type,
-                     FLAGS_begin_key, FLAGS_end_key, FLAGS_print_key,
-                     FLAGS_print_weight, FLAGS_symbols, FLAGS_initial_symbols,
-                     FLAGS_generate_filenames, FLAGS_filename_prefix,
-                     FLAGS_filename_suffix);
-
-  return 0;
+  return farprintstrings_main(argc, argv);
 }
index 17c6c46..1783085 100644 (file)
 namespace fst {
 namespace script {
 
-void FarCompileStrings(const std::vector<string> &in_fnames,
-                       const string &out_fname, const string &arc_type,
-                       const string &fst_type, const FarType &far_type,
-                       int32 generate_keys, FarEntryType fet, FarTokenType tt,
-                       const string &symbols_fname,
-                       const string &unknown_symbol, bool keep_symbols,
+void FarCompileStrings(const std::vector<std::string> &in_fnames,
+                       const std::string &out_fname,
+                       const std::string &arc_type, const std::string &fst_type,
+                       const FarType &far_type, int32 generate_keys,
+                       FarEntryType fet, FarTokenType tt,
+                       const std::string &symbols_fname,
+                       const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
-                       const string &key_prefix, const string &key_suffix) {
+                       const std::string &key_prefix,
+                       const std::string &key_suffix) {
   FarCompileStringsArgs args(in_fnames, out_fname, fst_type, far_type,
                              generate_keys, fet, tt, symbols_fname,
                              unknown_symbol, keep_symbols, initial_symbols,
@@ -26,50 +28,53 @@ void FarCompileStrings(const std::vector<string> &in_fnames,
   Apply<Operation<FarCompileStringsArgs>>("FarCompileStrings", arc_type, &args);
 }
 
-void FarCreate(const std::vector<string> &in_fnames, const string &out_fname,
-               const string &arc_type, const int32 generate_keys,
-               const FarType &far_type, const string &key_prefix,
-               const string &key_suffix) {
+void FarCreate(const std::vector<std::string> &in_fnames,
+               const std::string &out_fname, 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_fnames, out_fname, generate_keys, far_type, key_prefix,
                      key_suffix);
   Apply<Operation<FarCreateArgs>>("FarCreate", arc_type, &args);
 }
 
-bool FarEqual(const string &filename1, const string &filename2,
-              const string &arc_type, float delta, const string &begin_key,
-              const string &end_key) {
+bool FarEqual(const std::string &filename1, const std::string &filename2,
+              const std::string &arc_type, float delta,
+              const std::string &begin_key, const std::string &end_key) {
   FarEqualInnerArgs args(filename1, filename2, delta, begin_key, end_key);
   FarEqualArgs args_with_retval(args);
   Apply<Operation<FarEqualArgs>>("FarEqual", arc_type, &args_with_retval);
   return args_with_retval.retval;
 }
 
-void FarExtract(const std::vector<string> &ifilenames, const string &arc_type,
-                int32 generate_filenames, const string &keys,
-                const string &key_separator, const string &range_delimiter,
-                const string &filename_prefix, const string &filename_suffix) {
+void FarExtract(const std::vector<std::string> &ifilenames,
+                const std::string &arc_type, int32 generate_filenames,
+                const std::string &keys, const std::string &key_separator,
+                const std::string &range_delimiter,
+                const std::string &filename_prefix,
+                const std::string &filename_suffix) {
   FarExtractArgs args(ifilenames, generate_filenames, keys, key_separator,
                       range_delimiter, filename_prefix, filename_suffix);
   Apply<Operation<FarExtractArgs>>("FarExtract", arc_type, &args);
 }
 
-void FarInfo(const std::vector<string> &filenames, const string &arc_type,
-             const string &begin_key, const string &end_key,
-             const bool list_fsts) {
+void FarInfo(const std::vector<std::string> &filenames,
+             const std::string &arc_type, const std::string &begin_key,
+             const std::string &end_key, const bool list_fsts) {
   FarInfoArgs args(filenames, begin_key, end_key, list_fsts);
   Apply<Operation<FarInfoArgs>>("FarInfo", arc_type, &args);
 }
 
-void GetFarInfo(const std::vector<string> &filenames, const string &arc_type,
-                const string &begin_key, const string &end_key,
-                const bool list_fsts, FarInfoData *data) {
+void GetFarInfo(const std::vector<std::string> &filenames,
+                const std::string &arc_type, const std::string &begin_key,
+                const std::string &end_key, const bool list_fsts,
+                FarInfoData *data) {
   GetFarInfoArgs args(filenames, begin_key, end_key, list_fsts, data);
   Apply<Operation<GetFarInfoArgs>>("GetFarInfo", arc_type, &args);
 }
 
-bool FarIsomorphic(const string &filename1, const string &filename2,
-                   const string &arc_type, float delta, const string &begin_key,
-                   const string &end_key) {
+bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+                   const std::string &arc_type, float delta,
+                   const std::string &begin_key, const std::string &end_key) {
   FarIsomorphicInnerArgs args(filename1, filename2, delta, begin_key, end_key);
   FarIsomorphicArgs args_with_retval(args);
   Apply<Operation<FarIsomorphicArgs>>("FarIsomorphic", arc_type,
@@ -77,14 +82,15 @@ bool FarIsomorphic(const string &filename1, const string &filename2,
   return args_with_retval.retval;
 }
 
-void FarPrintStrings(const std::vector<string> &ifilenames,
-                     const string &arc_type, const FarEntryType entry_type,
-                     const FarTokenType token_type, const string &begin_key,
-                     const string &end_key, const bool print_key,
-                     const bool print_weight, const string &symbols_fname,
+void FarPrintStrings(const std::vector<std::string> &ifilenames,
+                     const std::string &arc_type, const FarEntryType entry_type,
+                     const FarTokenType token_type,
+                     const std::string &begin_key, const std::string &end_key,
+                     const bool print_key, const bool print_weight,
+                     const std::string &symbols_fname,
                      const bool initial_symbols, const int32 generate_filenames,
-                     const string &filename_prefix,
-                     const string &filename_suffix) {
+                     const std::string &filename_prefix,
+                     const std::string &filename_suffix) {
   FarPrintStringsArgs args(ifilenames, entry_type, token_type, begin_key,
                            end_key, print_key, print_weight, symbols_fname,
                            initial_symbols, generate_filenames, filename_prefix,
index a2ffe5f..c49f1bb 100644 (file)
@@ -16,7 +16,7 @@ namespace fst {
 
 namespace script {
 
-FarType GetFarType(const string &str) {
+FarType GetFarType(const std::string &str) {
   if (str == "fst") {
     return FAR_FST;
   } else if (str == "stlist") {
@@ -28,7 +28,7 @@ FarType GetFarType(const string &str) {
   }
 }
 
-bool GetFarEntryType(const string &str, FarEntryType *entry_type) {
+bool GetFarEntryType(const std::string &str, FarEntryType *entry_type) {
   if (str == "line") {
     *entry_type = FET_LINE;
   } else if (str == "file") {
@@ -39,7 +39,7 @@ bool GetFarEntryType(const string &str, FarEntryType *entry_type) {
   return true;
 }
 
-bool GetFarTokenType(const string &str, FarTokenType *token_type) {
+bool GetFarTokenType(const std::string &str, FarTokenType *token_type) {
   if (str == "symbol") {
     *token_type = FTT_SYMBOL;
   } else if (str == "byte") {
@@ -57,7 +57,7 @@ void ExpandArgs(int argc, char **argv, int *argcp, char ***argvp) {
 
 }  // namespace script
 
-string GetFarTypeString(FarType type) {
+std::string GetFarTypeString(FarType type) {
   switch (type) {
     case FAR_FST:
       return "fst";
index 6fd1331..4882dfc 100644 (file)
 namespace fst {
 namespace script {
 
-string LoadArcTypeFromFar(const string &far_fname) {
+std::string LoadArcTypeFromFar(const std::string &far_fname) {
   FarHeader hdr;
   if (!hdr.Read(far_fname)) {
     LOG(ERROR) << "Error reading FAR: " << far_fname;
     return "";
   }
-  string atype = hdr.ArcType();
+  std::string atype = hdr.ArcType();
   if (atype == "unknown") {
     LOG(ERROR) << "Empty FST archive: " << far_fname;
     return "";
@@ -28,7 +28,7 @@ string LoadArcTypeFromFar(const string &far_fname) {
   return atype;
 }
 
-string LoadArcTypeFromFst(const string &fst_fname) {
+std::string LoadArcTypeFromFst(const std::string &fst_fname) {
   FstHeader hdr;
   std::ifstream in(fst_fname, std::ios_base::in | std::ios_base::binary);
   if (!hdr.Read(in, fst_fname)) {
index 89e4b90..d7c9d72 100644 (file)
@@ -8,7 +8,7 @@
 
 namespace fst {
 
-bool IsSTList(const string &filename) {
+bool IsSTList(const std::string &filename) {
   std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
   int32 magic_number = 0;
index ad516d1..8e68153 100644 (file)
@@ -14,14 +14,23 @@ DEFINE_string(far_field_separator, "\t",
 namespace fst {
 
 // Computes the minimal length required to encode each line number as a decimal
-// number.
+// number, or zero if the number of lines could not be determined because the
+// file was not seekable.
 int KeySize(const char *filename) {
   std::ifstream istrm(filename);
   istrm.seekg(0);
-  string s;
+  // TODO(jrosenstock): Change this to is_regular_file when we can use C++17.
+  // Stream not seekable. This is really a hack to approximate is_regular_file.
+  // What we really want is that opening and reading the file twice gives the
+  // same result, which is only true for regular files. There may be devices
+  // that don't return an error on seek. At least we are able to catch the
+  // common cases of /dev/stdin and fifos.
+  if (istrm.rdstate() & std::ios_base::failbit) {
+    return 0;
+  }
+  std::string s;
   int nline = 0;
   while (getline(istrm, s)) ++nline;
-  istrm.seekg(0);
   return nline ? ceil(log10(nline + 1)) : 1;
 }
 
index bf7d4a2..e08b8d6 100644 (file)
@@ -6,7 +6,7 @@
 
 namespace fst {
 
-bool IsSTTable(const string &filename) {
+bool IsSTTable(const std::string &filename) {
   std::ifstream strm(filename);
   if (!strm.good()) return false;
 
index a7bbb1c..8737dde 100644 (file)
@@ -6,16 +6,16 @@ bin_PROGRAMS = fstlinear fstloglinearapply
 LDADD = libfstlinearscript.la ../../script/libfstscript.la \
     ../../lib/libfst.la -lm $(DL_LIBS)
 
-fstlinear_SOURCES = fstlinear.cc
+fstlinear_SOURCES = fstlinear.cc fstlinear-main.cc
 
-fstloglinearapply_SOURCES = fstloglinearapply.cc
+fstloglinearapply_SOURCES = fstloglinearapply.cc fstloglinearapply-main.cc
 endif
 
 if HAVE_SCRIPT
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 16:0:0 -lm $(DL_LIBS)
+libfstlinearscript_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
-                                                       ../../lib/libfst.la -lm $(DL_LIBS)
+                               ../../lib/libfst.la -lm $(DL_LIBS)
 endif
 
 if HAVE_SCRIPT
index dba29dc..4297313 100644 (file)
@@ -173,16 +173,19 @@ linear_tagger_fst_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_SCRIPT_FALSE@am_linear_tagger_fst_la_rpath = -rpath $(libfstdir)
 @HAVE_SCRIPT_TRUE@am_linear_tagger_fst_la_rpath = -rpath $(libfstdir)
 PROGRAMS = $(bin_PROGRAMS)
-am__fstlinear_SOURCES_DIST = fstlinear.cc
-@HAVE_BIN_TRUE@am_fstlinear_OBJECTS = fstlinear.$(OBJEXT)
+am__fstlinear_SOURCES_DIST = fstlinear.cc fstlinear-main.cc
+@HAVE_BIN_TRUE@am_fstlinear_OBJECTS = fstlinear.$(OBJEXT) \
+@HAVE_BIN_TRUE@        fstlinear-main.$(OBJEXT)
 fstlinear_OBJECTS = $(am_fstlinear_OBJECTS)
 fstlinear_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@fstlinear_DEPENDENCIES = libfstlinearscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__fstloglinearapply_SOURCES_DIST = fstloglinearapply.cc
+am__fstloglinearapply_SOURCES_DIST = fstloglinearapply.cc \
+       fstloglinearapply-main.cc
 @HAVE_BIN_TRUE@am_fstloglinearapply_OBJECTS =  \
-@HAVE_BIN_TRUE@        fstloglinearapply.$(OBJEXT)
+@HAVE_BIN_TRUE@        fstloglinearapply.$(OBJEXT) \
+@HAVE_BIN_TRUE@        fstloglinearapply-main.$(OBJEXT)
 fstloglinearapply_OBJECTS = $(am_fstloglinearapply_OBJECTS)
 fstloglinearapply_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@fstloglinearapply_DEPENDENCIES = libfstlinearscript.la \
@@ -397,12 +400,12 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@LDADD = libfstlinearscript.la ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@    ../../lib/libfst.la -lm $(DL_LIBS)
 
-@HAVE_BIN_TRUE@fstlinear_SOURCES = fstlinear.cc
-@HAVE_BIN_TRUE@fstloglinearapply_SOURCES = fstloglinearapply.cc
+@HAVE_BIN_TRUE@fstlinear_SOURCES = fstlinear.cc fstlinear-main.cc
+@HAVE_BIN_TRUE@fstloglinearapply_SOURCES = fstloglinearapply.cc fstloglinearapply-main.cc
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 16:0:0 -lm $(DL_LIBS)
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
-@HAVE_SCRIPT_TRUE@                                                     ../../lib/libfst.la -lm $(DL_LIBS)
+@HAVE_SCRIPT_TRUE@                               ../../lib/libfst.la -lm $(DL_LIBS)
 
 @HAVE_SCRIPT_FALSE@libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
 @HAVE_SCRIPT_TRUE@libfst_LTLIBRARIES = linear_tagger-fst.la \
@@ -589,7 +592,9 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstlinear.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstloglinearapply.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-classifier-fst.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linear-tagger-fst.Plo@am__quote@
diff --git a/src/extensions/linear/fstlinear-main.cc b/src/extensions/linear/fstlinear-main.cc
new file mode 100644 (file)
index 0000000..3e7ccc8
--- /dev/null
@@ -0,0 +1,35 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+
+#include <fst/extensions/linear/linearscript.h>
+
+#include <fst/flags.h>
+
+DECLARE_string(arc_type);
+DECLARE_string(epsilon_symbol);
+DECLARE_string(unknown_symbol);
+DECLARE_string(vocab);
+DECLARE_string(out);
+DECLARE_string(save_isymbols);
+DECLARE_string(save_fsymbols);
+DECLARE_string(save_osymbols);
+
+int fstlinear_main(int argc, char **argv) {
+  // TODO(wuke): more detailed usage
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(argv[0], &argc, &argv, true);
+  fst::script::ValidateDelimiter();
+  fst::script::ValidateEmptySymbol();
+
+  if (argc == 1) {
+    ShowUsage();
+    return 1;
+  }
+
+  fst::script::LinearCompile(FLAGS_arc_type, FLAGS_epsilon_symbol,
+                                 FLAGS_unknown_symbol, FLAGS_vocab, argv + 1,
+                                 argc - 1, FLAGS_out, FLAGS_save_isymbols,
+                                 FLAGS_save_fsymbols, FLAGS_save_osymbols);
+
+  return 0;
+}
index 502a385..a0090de 100644 (file)
@@ -1,36 +1,17 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/extensions/linear/linearscript.h>
-
 #include <fst/flags.h>
 
 DEFINE_string(arc_type, "standard", "Output arc type");
-
 DEFINE_string(epsilon_symbol, "<eps>", "Epsilon symbol");
 DEFINE_string(unknown_symbol, "<unk>", "Unknown word symbol");
-
 DEFINE_string(vocab, "", "Path to the vocabulary file");
 DEFINE_string(out, "", "Path to the output binary");
-
 DEFINE_string(save_isymbols, "", "Save input symbol table to file");
 DEFINE_string(save_fsymbols, "", "Save feature symbol table to file");
 DEFINE_string(save_osymbols, "", "Save output symbol table to file");
 
-int main(int argc, char **argv) {
-  // TODO(wuke): more detailed usage
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(argv[0], &argc, &argv, true);
-  fst::script::ValidateDelimiter();
-  fst::script::ValidateEmptySymbol();
-
-  if (argc == 1) {
-    ShowUsage();
-    return 1;
-  }
+int fstlinear_main(int argc, char **argv);
 
-  fst::script::LinearCompile(FLAGS_arc_type, FLAGS_epsilon_symbol,
-                                 FLAGS_unknown_symbol, FLAGS_vocab, argv + 1,
-                                 argc - 1, FLAGS_out, FLAGS_save_isymbols,
-                                 FLAGS_save_fsymbols, FLAGS_save_osymbols);
-}
+int main(int argc, char **argv) { return fstlinear_main(argc, argv); }
diff --git a/src/extensions/linear/fstloglinearapply-main.cc b/src/extensions/linear/fstloglinearapply-main.cc
new file mode 100644 (file)
index 0000000..4d39e13
--- /dev/null
@@ -0,0 +1,50 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+
+#include <fst/extensions/linear/linear-fst.h>
+#include <fst/extensions/linear/loglinear-apply.h>
+#include <fst/vector-fst.h>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+
+DECLARE_bool(normalize);
+
+int fstloglinearapply_main(int argc, char **argv) {
+  std::string usage =
+      "Applies an FST to another FST, treating the second as a log-linear "
+      "model.\n\n  "
+      "Usage: ";
+  usage += argv[0];
+  usage += " in.fst linear.fst [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc < 3 || argc > 4) {
+    ShowUsage();
+    return 1;
+  }
+
+  std::string in_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
+  std::string linear_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+  std::string out_name =
+      (argc > 3 && (strcmp(argv[3], "-") != 0)) ? argv[3] : "";
+
+  if (in_name.empty() && linear_name.empty()) {
+    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
+    return 1;
+  }
+
+  fst::StdFst *ifst1 = fst::StdFst::Read(in_name);
+  if (!ifst1) return 1;
+
+  fst::StdFst *ifst2 = fst::StdFst::Read(linear_name);
+  if (!ifst2) return 1;
+
+  fst::StdVectorFst ofst;
+
+  fst::LogLinearApply(*ifst1, *ifst2, &ofst, FLAGS_normalize);
+
+  return !ofst.Write(out_name);
+}
index 69e269d..4a8ac68 100644 (file)
@@ -2,50 +2,10 @@
 // finite-state transducer library.
 
 #include <fst/compat.h>
-#include <fst/extensions/linear/linear-fst.h>
-#include <fst/extensions/linear/loglinear-apply.h>
-#include <fst/vector-fst.h>
-
 #include <fst/flags.h>
-#include <fst/log.h>
 
 DEFINE_bool(normalize, true, "Normalize to get posterior");
 
-int main(int argc, char **argv) {
-  string usage =
-      "Applies an FST to another FST, treating the second as a log-linear "
-      "model.\n\n  "
-      "Usage: ";
-  usage += argv[0];
-  usage += " in.fst linear.fst [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc < 3 || argc > 4) {
-    ShowUsage();
-    return 1;
-  }
-
-  string in_name = strcmp(argv[1], "-") != 0 ? argv[1] : "";
-  string linear_name = (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
-  string out_name = argc > 3 ? argv[3] : "";
-
-  if (in_name.empty() && linear_name.empty()) {
-    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
-    return 1;
-  }
-
-  fst::StdFst *ifst1 = fst::StdFst::Read(in_name);
-  if (!ifst1) return 1;
-
-  fst::StdFst *ifst2 = fst::StdFst::Read(linear_name);
-  if (!ifst2) return 1;
-
-  fst::StdVectorFst ofst;
-
-  LogLinearApply(*ifst1, *ifst2, &ofst, FLAGS_normalize);
-
-  ofst.Write(out_name);
+int fstloglinearapply_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return fstloglinearapply_main(argc, argv); }
index be15886..46c2600 100644 (file)
@@ -42,11 +42,13 @@ bool ValidateEmptySymbol() {
   return okay;
 }
 
-void LinearCompile(const string &arc_type, const string &epsilon_symbol,
-                   const string &unknown_symbol, const string &vocab,
-                   char **models, int models_len, const string &out,
-                   const string &save_isymbols, const string &save_fsymbols,
-                   const string &save_osymbols) {
+void LinearCompile(const std::string &arc_type,
+                   const std::string &epsilon_symbol,
+                   const std::string &unknown_symbol, const std::string &vocab,
+                   char **models, int models_len, const std::string &out,
+                   const std::string &save_isymbols,
+                   const std::string &save_fsymbols,
+                   const std::string &save_osymbols) {
   LinearCompileArgs args(epsilon_symbol, unknown_symbol, vocab, models,
                          models_len, out, save_isymbols, save_fsymbols,
                          save_osymbols);
@@ -57,26 +59,26 @@ void LinearCompile(const string &arc_type, const string &epsilon_symbol,
 REGISTER_FST_LINEAR_OPERATIONS(StdArc);
 REGISTER_FST_LINEAR_OPERATIONS(LogArc);
 
-void SplitByWhitespace(const string &str, std::vector<string> *out) {
+void SplitByWhitespace(const std::string &str, std::vector<std::string> *out) {
   out->clear();
   std::istringstream strm(str);
-  string buf;
+  std::string buf;
   while (strm >> buf) out->push_back(buf);
 }
 
 int ScanNumClasses(char **models, int models_len) {
-  std::set<string> preds;
+  std::set<std::string> preds;
   for (int i = 0; i < models_len; ++i) {
     std::ifstream in(models[i]);
     if (!in) LOG(FATAL) << "Failed to open " << models[i];
 
-    string line;
+    std::string line;
     std::getline(in, line);
 
     size_t num_line = 1;
     while (std::getline(in, line)) {
       ++num_line;
-      std::vector<string> fields;
+      std::vector<std::string> fields;
       SplitByWhitespace(line, &fields);
       if (fields.size() != 3)
         LOG(FATAL) << "Wrong number of fields in source " << models[i]
index 42190c7..3c6e6e4 100644 (file)
@@ -8,7 +8,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 16:0:0
+libfstlookahead_la_LDFLAGS = -version-info 17:0:0
 libfstlookahead_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
index 8d32bf3..20c76c2 100644 (file)
@@ -381,7 +381,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 16:0:0
+libfstlookahead_la_LDFLAGS = -version-info 17:0:0
 libfstlookahead_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -module
index 3474bff..8002e2d 100644 (file)
@@ -8,19 +8,19 @@ LDADD = libfstmpdtscript.la      \
     ../../script/libfstscript.la \
     ../../lib/libfst.la -lm $(DL_LIBS)
 
-mpdtcompose_SOURCES = mpdtcompose.cc
+mpdtcompose_SOURCES = mpdtcompose.cc mpdtcompose-main.cc
 
-mpdtexpand_SOURCES = mpdtexpand.cc
+mpdtexpand_SOURCES = mpdtexpand.cc mpdtexpand-main.cc
 
-mpdtinfo_SOURCES = mpdtinfo.cc
+mpdtinfo_SOURCES = mpdtinfo.cc mpdtinfo-main.cc
 
-mpdtreverse_SOURCES = mpdtreverse.cc
+mpdtreverse_SOURCES = mpdtreverse.cc mpdtreverse-main.cc
 endif
 
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 16:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 17:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 89544af..4f57440 100644 (file)
@@ -151,32 +151,36 @@ libfstmpdtscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstmpdtscript_la_rpath = -rpath $(libdir)
 PROGRAMS = $(bin_PROGRAMS)
-am__mpdtcompose_SOURCES_DIST = mpdtcompose.cc
-@HAVE_BIN_TRUE@am_mpdtcompose_OBJECTS = mpdtcompose.$(OBJEXT)
+am__mpdtcompose_SOURCES_DIST = mpdtcompose.cc mpdtcompose-main.cc
+@HAVE_BIN_TRUE@am_mpdtcompose_OBJECTS = mpdtcompose.$(OBJEXT) \
+@HAVE_BIN_TRUE@        mpdtcompose-main.$(OBJEXT)
 mpdtcompose_OBJECTS = $(am_mpdtcompose_OBJECTS)
 mpdtcompose_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@mpdtcompose_DEPENDENCIES = libfstmpdtscript.la \
 @HAVE_BIN_TRUE@        ../pdt/libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__mpdtexpand_SOURCES_DIST = mpdtexpand.cc
-@HAVE_BIN_TRUE@am_mpdtexpand_OBJECTS = mpdtexpand.$(OBJEXT)
+am__mpdtexpand_SOURCES_DIST = mpdtexpand.cc mpdtexpand-main.cc
+@HAVE_BIN_TRUE@am_mpdtexpand_OBJECTS = mpdtexpand.$(OBJEXT) \
+@HAVE_BIN_TRUE@        mpdtexpand-main.$(OBJEXT)
 mpdtexpand_OBJECTS = $(am_mpdtexpand_OBJECTS)
 mpdtexpand_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@mpdtexpand_DEPENDENCIES = libfstmpdtscript.la \
 @HAVE_BIN_TRUE@        ../pdt/libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__mpdtinfo_SOURCES_DIST = mpdtinfo.cc
-@HAVE_BIN_TRUE@am_mpdtinfo_OBJECTS = mpdtinfo.$(OBJEXT)
+am__mpdtinfo_SOURCES_DIST = mpdtinfo.cc mpdtinfo-main.cc
+@HAVE_BIN_TRUE@am_mpdtinfo_OBJECTS = mpdtinfo.$(OBJEXT) \
+@HAVE_BIN_TRUE@        mpdtinfo-main.$(OBJEXT)
 mpdtinfo_OBJECTS = $(am_mpdtinfo_OBJECTS)
 mpdtinfo_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@mpdtinfo_DEPENDENCIES = libfstmpdtscript.la \
 @HAVE_BIN_TRUE@        ../pdt/libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__mpdtreverse_SOURCES_DIST = mpdtreverse.cc
-@HAVE_BIN_TRUE@am_mpdtreverse_OBJECTS = mpdtreverse.$(OBJEXT)
+am__mpdtreverse_SOURCES_DIST = mpdtreverse.cc mpdtreverse-main.cc
+@HAVE_BIN_TRUE@am_mpdtreverse_OBJECTS = mpdtreverse.$(OBJEXT) \
+@HAVE_BIN_TRUE@        mpdtreverse-main.$(OBJEXT)
 mpdtreverse_OBJECTS = $(am_mpdtreverse_OBJECTS)
 mpdtreverse_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@mpdtreverse_DEPENDENCIES = libfstmpdtscript.la \
@@ -392,13 +396,13 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@    ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@    ../../lib/libfst.la -lm $(DL_LIBS)
 
-@HAVE_BIN_TRUE@mpdtcompose_SOURCES = mpdtcompose.cc
-@HAVE_BIN_TRUE@mpdtexpand_SOURCES = mpdtexpand.cc
-@HAVE_BIN_TRUE@mpdtinfo_SOURCES = mpdtinfo.cc
-@HAVE_BIN_TRUE@mpdtreverse_SOURCES = mpdtreverse.cc
+@HAVE_BIN_TRUE@mpdtcompose_SOURCES = mpdtcompose.cc mpdtcompose-main.cc
+@HAVE_BIN_TRUE@mpdtexpand_SOURCES = mpdtexpand.cc mpdtexpand-main.cc
+@HAVE_BIN_TRUE@mpdtinfo_SOURCES = mpdtinfo.cc mpdtinfo-main.cc
+@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 16:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 17:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
@@ -545,9 +549,13 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtcompose.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtexpand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtreverse.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpdtscript.Plo@am__quote@
 
diff --git a/src/extensions/mpdt/mpdtcompose-main.cc b/src/extensions/mpdt/mpdtcompose-main.cc
new file mode 100644 (file)
index 0000000..35434c6
--- /dev/null
@@ -0,0 +1,84 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Composes an MPDT and an FST.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/mpdt/mpdtscript.h>
+#include <fst/extensions/mpdt/read_write_utils.h>
+#include <fst/extensions/pdt/getters.h>
+#include <fst/util.h>
+
+DECLARE_string(mpdt_parentheses);
+DECLARE_bool(left_mpdt);
+DECLARE_bool(connect);
+DECLARE_string(compose_filter);
+
+int mpdtcompose_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::MPdtComposeOptions;
+  using fst::PdtComposeFilter;
+  using fst::ReadLabelTriples;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+
+  std::string usage = "Compose an MPDT and an FST.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt in.fst [out.mpdt]\n";
+  usage += " in.fst in.pdt [out.mpdt]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc < 3 || argc > 4) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
+
+  if (in1_name.empty() && in2_name.empty()) {
+    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
+    return 1;
+  }
+
+  std::unique_ptr<FstClass> ifst1(FstClass::Read(in1_name));
+  if (!ifst1) return 1;
+  std::unique_ptr<FstClass> ifst2(FstClass::Read(in2_name));
+  if (!ifst2) return 1;
+
+  if (FLAGS_mpdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  std::vector<int64> assignments;
+  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
+    return 1;
+  }
+
+  VectorFstClass ofst(ifst1->ArcType());
+
+  PdtComposeFilter compose_filter;
+  if (!s::GetPdtComposeFilter(FLAGS_compose_filter, &compose_filter)) {
+    LOG(ERROR) << argv[0] << ": Unknown or unsupported compose filter type: "
+               << FLAGS_compose_filter;
+    return 1;
+  }
+
+  const MPdtComposeOptions opts(FLAGS_connect, compose_filter);
+
+  s::MPdtCompose(*ifst1, *ifst2, parens, assignments, &ofst, opts,
+                 FLAGS_left_mpdt);
+
+  return !ofst.Write(out_name);
+}
index 351033a..c1e675b 100644 (file)
@@ -3,19 +3,7 @@
 //
 // Composes an MPDT and an FST.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/mpdt/mpdtscript.h>
-#include <fst/extensions/mpdt/read_write_utils.h>
-#include <fst/extensions/pdt/getters.h>
-#include <fst/util.h>
 
 DEFINE_string(mpdt_parentheses, "",
               "MPDT parenthesis label pairs with assignments");
@@ -25,65 +13,6 @@ DEFINE_string(compose_filter, "paren",
               "Composition filter, one of: \"expand\", \"expand_paren\", "
               "\"paren\"");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::MPdtComposeOptions;
-  using fst::PdtComposeFilter;
-  using fst::ReadLabelTriples;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-
-  string usage = "Compose an MPDT and an FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt in.fst [out.mpdt]\n";
-  usage += " in.fst in.pdt [out.mpdt]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc < 3 || argc > 4) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
-
-  if (in1_name.empty() && in2_name.empty()) {
-    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
-    return 1;
-  }
-
-  std::unique_ptr<FstClass> ifst1(FstClass::Read(in1_name));
-  if (!ifst1) return 1;
-  std::unique_ptr<FstClass> ifst2(FstClass::Read(in2_name));
-  if (!ifst2) return 1;
-
-  if (FLAGS_mpdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  std::vector<int64> assignments;
-  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false))
-    return 1;
-
-  VectorFstClass ofst(ifst1->ArcType());
-
-  PdtComposeFilter compose_filter;
-  if (!s::GetPdtComposeFilter(FLAGS_compose_filter, &compose_filter)) {
-    LOG(ERROR) << argv[0] << ": Unknown or unsupported compose filter type: "
-               << FLAGS_compose_filter;
-    return 1;
-  }
-
-  const MPdtComposeOptions opts(FLAGS_connect, compose_filter);
-
-  s::MPdtCompose(*ifst1, *ifst2, parens, assignments, &ofst, opts,
-                 FLAGS_left_mpdt);
-
-  ofst.Write(out_name);
+int mpdtcompose_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return mpdtcompose_main(argc, argv); }
diff --git a/src/extensions/mpdt/mpdtexpand-main.cc b/src/extensions/mpdt/mpdtexpand-main.cc
new file mode 100644 (file)
index 0000000..a484cbf
--- /dev/null
@@ -0,0 +1,65 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Expands a (bounded-stack) MPDT as an FST.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/mpdt/mpdtscript.h>
+#include <fst/extensions/mpdt/read_write_utils.h>
+#include <fst/util.h>
+
+DECLARE_string(mpdt_parentheses);
+DECLARE_bool(connect);
+DECLARE_bool(keep_parentheses);
+
+int mpdtexpand_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+  using fst::ReadLabelTriples;
+  using fst::MPdtExpandOptions;
+
+  std::string usage = "Expand a (bounded-stack) MPDT as an FST.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+  if (!ifst) return 1;
+
+  if (FLAGS_mpdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  std::vector<int64> assignments;
+  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
+    return 1;
+  }
+
+  VectorFstClass ofst(ifst->ArcType());
+
+  const MPdtExpandOptions opts(FLAGS_connect, FLAGS_keep_parentheses);
+
+  s::MPdtExpand(*ifst, parens, assignments, &ofst, opts);
+
+  return !ofst.Write(out_name);
+}
index fb24b3a..7f4003b 100644 (file)
@@ -3,66 +3,13 @@
 //
 // Expands a (bounded-stack) MPDT as an FST.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/mpdt/mpdtscript.h>
-#include <fst/extensions/mpdt/read_write_utils.h>
-#include <fst/util.h>
 
 DEFINE_string(mpdt_parentheses, "",
               "MPDT parenthesis label pairs with assignments");
 DEFINE_bool(connect, true, "Trim output?");
 DEFINE_bool(keep_parentheses, false, "Keep PDT parentheses in result?");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-  using fst::ReadLabelTriples;
-  using fst::MPdtExpandOptions;
-
-  string usage = "Expand a (bounded-stack) MPDT as an FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
-
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
-
-  if (FLAGS_mpdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  std::vector<int64> assignments;
-  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false))
-    return 1;
-
-  VectorFstClass ofst(ifst->ArcType());
-
-  const MPdtExpandOptions opts(FLAGS_connect, FLAGS_keep_parentheses);
-
-  s::MPdtExpand(*ifst, parens, assignments, &ofst, opts);
-
-  ofst.Write(out_name);
+int mpdtexpand_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return mpdtexpand_main(argc, argv); }
diff --git a/src/extensions/mpdt/mpdtinfo-main.cc b/src/extensions/mpdt/mpdtinfo-main.cc
new file mode 100644 (file)
index 0000000..74d56b9
--- /dev/null
@@ -0,0 +1,58 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Prints out various information about an MPDT such as number of states, arcs,
+// and parentheses.
+
+#include <cstring>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+
+#include <fst/extensions/mpdt/mpdtscript.h>
+#include <fst/extensions/mpdt/read_write_utils.h>
+#include <fst/util.h>
+
+DECLARE_string(mpdt_parentheses);
+
+int mpdtinfo_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::ReadLabelTriples;
+
+  std::string usage = "Prints out information about an MPDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 2) {
+    ShowUsage();
+    return 1;
+  }
+
+  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_mpdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  std::vector<int64> assignments;
+  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
+    return 1;
+  }
+
+  s::PrintMPdtInfo(*ifst, parens, assignments);
+
+  return 0;
+}
index b8d7d4a..cc501fe 100644 (file)
@@ -4,55 +4,11 @@
 // Prints out various information about an MPDT such as number of states, arcs,
 // and parentheses.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/mpdt/mpdtscript.h>
-#include <fst/extensions/mpdt/read_write_utils.h>
-#include <fst/util.h>
 
 DEFINE_string(mpdt_parentheses, "",
               "MPDT parenthesis label pairs with assignments");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::ReadLabelTriples;
-
-  string usage = "Prints out information about an MPDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 2) {
-    ShowUsage();
-    return 1;
-  }
-
-  const 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_mpdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  std::vector<int64> assignments;
-  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false))
-    return 1;
-
-  s::PrintMPdtInfo(*ifst, parens, assignments);
+int mpdtinfo_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return mpdtinfo_main(argc, argv); }
diff --git a/src/extensions/mpdt/mpdtreverse-main.cc b/src/extensions/mpdt/mpdtreverse-main.cc
new file mode 100644 (file)
index 0000000..d266905
--- /dev/null
@@ -0,0 +1,69 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Reverses an MPDT.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/mpdt/mpdtscript.h>
+#include <fst/extensions/mpdt/read_write_utils.h>
+#include <fst/util.h>
+
+DECLARE_string(mpdt_parentheses);
+DECLARE_string(mpdt_new_parentheses);
+
+int mpdtreverse_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::ReadLabelTriples;
+  using fst::WriteLabelTriples;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+
+  std::string usage = "Reverse an MPDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+  if (!ifst) return 1;
+
+  if (FLAGS_mpdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  if (FLAGS_mpdt_new_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No MPDT output parenthesis label file provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  std::vector<int64> assignments;
+  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false)) {
+    return 1;
+  }
+
+  VectorFstClass ofst(ifst->ArcType());
+
+  s::MPdtReverse(*ifst, parens, &assignments, &ofst);
+
+  if (!ofst.Write(out_name)) return 1;
+
+  return !WriteLabelTriples(FLAGS_mpdt_new_parentheses, parens, assignments);
+}
index 7bde1a1..37673ca 100644 (file)
@@ -3,73 +3,13 @@
 //
 // Reverses an MPDT.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/mpdt/mpdtscript.h>
-#include <fst/extensions/mpdt/read_write_utils.h>
-#include <fst/util.h>
 
 DEFINE_string(mpdt_parentheses, "",
               "MPDT parenthesis label pairs with assignments.");
-
 DEFINE_string(mpdt_new_parentheses, "",
               "Output for reassigned parentheses and stacks");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::ReadLabelTriples;
-  using fst::WriteLabelTriples;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-
-  string usage = "Reverse an MPDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
-
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
-
-  if (FLAGS_mpdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No MPDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  if (FLAGS_mpdt_new_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No MPDT output parenthesis label file provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  std::vector<int64> assignments;
-  if (!ReadLabelTriples(FLAGS_mpdt_parentheses, &parens, &assignments, false))
-    return 1;
-
-  VectorFstClass ofst(ifst->ArcType());
-
-  s::MPdtReverse(*ifst, parens, &assignments, &ofst);
-
-  ofst.Write(out_name);
-
-  if (!WriteLabelTriples(FLAGS_mpdt_new_parentheses, parens, assignments))
-    return 1;
+int mpdtreverse_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return mpdtreverse_main(argc, argv); }
index 6174873..ebdda86 100644 (file)
@@ -9,5 +9,5 @@ ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -module
 
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 16:0:0
+libfstngram_la_LDFLAGS = -version-info 17:0:0
 libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
index 7cdf643..425f657 100644 (file)
@@ -355,7 +355,7 @@ lib_LTLIBRARIES = libfstngram.la
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -module
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 16:0:0
+libfstngram_la_LDFLAGS = -version-info 17:0:0
 libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 all: all-am
 
index be26f3d..10b249f 100644 (file)
 
 #include <fst/extensions/ngram/nthbit.h>
 
-#ifndef __BMI2__
-// This table is generated using:
+#if defined(__arm__)  // 32-bit ARM
+
+// ARM64 is detected with __aarch64__.
+
+// ARM32 has a poor implementation of __builtin_popcount, so any nth_bit
+// based on that is slow.  Use this table-based version instead.
+
+// These tables were generated using:
 //
-//  unsigned int nth_bit_scan(uint64 v, unsigned int r) {
-//    int i=0;
-//    for (; i<64; i++) {
+//  uint32 nth_bit_scan(uint64 v, uint32 r) {
+//    for (int i = 0; i < 64; ++i) {
 //      if ((r -= v & 1) == 0) return i;
 //      v >>= 1;
 //    }
-//    return i;
+//    return -1;
+//  }
+//
+//  printf("static const uint8 nth_bit_bit_count[256] = {\n");
+//  for (size_t i = 0; i < 256; ++i) {
+//    printf("%d, ", __builtin_popcount(i));
+//    if (i % 16 == 15) printf("\n");
+//  }
+//  printf("};\n");
+//
+//  printf("static const uint8 nth_bit_bit_pos[8][256] = {{\n");
+//  for (size_t j = 0; j < 8; ++j) {
+//    for (size_t i = 0; i < 256; ++i) {
+//      uint8 pos = nth_bit_scan(i, j);
+//      printf("%d, ", pos);
+//      if (i % 16 == 15) printf("\n");
+//    }
+//    if (j != 7) printf("}, {\n");
 //  }
+//  printf("}};\n");
+//
+// This table contains the popcount of 1-byte values:
+// nth_bit_bit_count[v] == __builtin_popcount(v).
+static const uint8 nth_bit_bit_count[256] = {
+    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
+    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
+
+// This table contains the bit position of the r-th set bit in v, for 1-byte v,
+// (or 255 if there are fewer than r bits set, but those values are never used):
+// nth_bit_bit_pos[r][v] == nth_bit_scan(v, r).
+static const uint8 nth_bit_bit_pos[8][256] = {
+    {
+        255, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0,
+        1,   0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0,
+        2,   0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0,
+        1,   0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0,
+        3,   0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0,
+        1,   0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0,
+        2,   0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0,
+        1,   0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+        4,   0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0,
+        1,   0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0,
+        2,   0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0,
+        1,   0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+    },
+    {
+        255, 255, 255, 1, 255, 2, 2, 1, 255, 3, 3,   1, 3, 2, 2,   1, 255, 4,
+        4,   1,   4,   2, 2,   1, 4, 3, 3,   1, 3,   2, 2, 1, 255, 5, 5,   1,
+        5,   2,   2,   1, 5,   3, 3, 1, 3,   2, 2,   1, 5, 4, 4,   1, 4,   2,
+        2,   1,   4,   3, 3,   1, 3, 2, 2,   1, 255, 6, 6, 1, 6,   2, 2,   1,
+        6,   3,   3,   1, 3,   2, 2, 1, 6,   4, 4,   1, 4, 2, 2,   1, 4,   3,
+        3,   1,   3,   2, 2,   1, 6, 5, 5,   1, 5,   2, 2, 1, 5,   3, 3,   1,
+        3,   2,   2,   1, 5,   4, 4, 1, 4,   2, 2,   1, 4, 3, 3,   1, 3,   2,
+        2,   1,   255, 7, 7,   1, 7, 2, 2,   1, 7,   3, 3, 1, 3,   2, 2,   1,
+        7,   4,   4,   1, 4,   2, 2, 1, 4,   3, 3,   1, 3, 2, 2,   1, 7,   5,
+        5,   1,   5,   2, 2,   1, 5, 3, 3,   1, 3,   2, 2, 1, 5,   4, 4,   1,
+        4,   2,   2,   1, 4,   3, 3, 1, 3,   2, 2,   1, 7, 6, 6,   1, 6,   2,
+        2,   1,   6,   3, 3,   1, 3, 2, 2,   1, 6,   4, 4, 1, 4,   2, 2,   1,
+        4,   3,   3,   1, 3,   2, 2, 1, 6,   5, 5,   1, 5, 2, 2,   1, 5,   3,
+        3,   1,   3,   2, 2,   1, 5, 4, 4,   1, 4,   2, 2, 1, 4,   3, 3,   1,
+        3,   2,   2,   1,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 2, 255, 255, 255, 3, 255, 3, 3, 2,
+        255, 255, 255, 4,   255, 4,   4,   2, 255, 4,   4,   3, 4,   3, 3, 2,
+        255, 255, 255, 5,   255, 5,   5,   2, 255, 5,   5,   3, 5,   3, 3, 2,
+        255, 5,   5,   4,   5,   4,   4,   2, 5,   4,   4,   3, 4,   3, 3, 2,
+        255, 255, 255, 6,   255, 6,   6,   2, 255, 6,   6,   3, 6,   3, 3, 2,
+        255, 6,   6,   4,   6,   4,   4,   2, 6,   4,   4,   3, 4,   3, 3, 2,
+        255, 6,   6,   5,   6,   5,   5,   2, 6,   5,   5,   3, 5,   3, 3, 2,
+        6,   5,   5,   4,   5,   4,   4,   2, 5,   4,   4,   3, 4,   3, 3, 2,
+        255, 255, 255, 7,   255, 7,   7,   2, 255, 7,   7,   3, 7,   3, 3, 2,
+        255, 7,   7,   4,   7,   4,   4,   2, 7,   4,   4,   3, 4,   3, 3, 2,
+        255, 7,   7,   5,   7,   5,   5,   2, 7,   5,   5,   3, 5,   3, 3, 2,
+        7,   5,   5,   4,   5,   4,   4,   2, 5,   4,   4,   3, 4,   3, 3, 2,
+        255, 7,   7,   6,   7,   6,   6,   2, 7,   6,   6,   3, 6,   3, 3, 2,
+        7,   6,   6,   4,   6,   4,   4,   2, 6,   4,   4,   3, 4,   3, 3, 2,
+        7,   6,   6,   5,   6,   5,   5,   2, 6,   5,   5,   3, 5,   3, 3, 2,
+        6,   5,   5,   4,   5,   4,   4,   2, 5,   4,   4,   3, 4,   3, 3, 2,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 3,   255, 255, 255, 255, 255, 255, 255, 4,   255, 255, 255, 4,
+        255, 4,   4,   3,   255, 255, 255, 255, 255, 255, 255, 5,   255, 255,
+        255, 5,   255, 5,   5,   3,   255, 255, 255, 5,   255, 5,   5,   4,
+        255, 5,   5,   4,   5,   4,   4,   3,   255, 255, 255, 255, 255, 255,
+        255, 6,   255, 255, 255, 6,   255, 6,   6,   3,   255, 255, 255, 6,
+        255, 6,   6,   4,   255, 6,   6,   4,   6,   4,   4,   3,   255, 255,
+        255, 6,   255, 6,   6,   5,   255, 6,   6,   5,   6,   5,   5,   3,
+        255, 6,   6,   5,   6,   5,   5,   4,   6,   5,   5,   4,   5,   4,
+        4,   3,   255, 255, 255, 255, 255, 255, 255, 7,   255, 255, 255, 7,
+        255, 7,   7,   3,   255, 255, 255, 7,   255, 7,   7,   4,   255, 7,
+        7,   4,   7,   4,   4,   3,   255, 255, 255, 7,   255, 7,   7,   5,
+        255, 7,   7,   5,   7,   5,   5,   3,   255, 7,   7,   5,   7,   5,
+        5,   4,   7,   5,   5,   4,   5,   4,   4,   3,   255, 255, 255, 7,
+        255, 7,   7,   6,   255, 7,   7,   6,   7,   6,   6,   3,   255, 7,
+        7,   6,   7,   6,   6,   4,   7,   6,   6,   4,   6,   4,   4,   3,
+        255, 7,   7,   6,   7,   6,   6,   5,   7,   6,   6,   5,   6,   5,
+        5,   3,   7,   6,   6,   5,   6,   5,   5,   4,   6,   5,   5,   4,
+        5,   4,   4,   3,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 4,   255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 5,   255, 255, 255, 255, 255, 255, 255, 5,
+        255, 255, 255, 5,   255, 5,   5,   4,   255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 6,   255, 255, 255, 255,
+        255, 255, 255, 6,   255, 255, 255, 6,   255, 6,   6,   4,   255, 255,
+        255, 255, 255, 255, 255, 6,   255, 255, 255, 6,   255, 6,   6,   5,
+        255, 255, 255, 6,   255, 6,   6,   5,   255, 6,   6,   5,   6,   5,
+        5,   4,   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 7,   255, 255, 255, 255, 255, 255, 255, 7,   255, 255,
+        255, 7,   255, 7,   7,   4,   255, 255, 255, 255, 255, 255, 255, 7,
+        255, 255, 255, 7,   255, 7,   7,   5,   255, 255, 255, 7,   255, 7,
+        7,   5,   255, 7,   7,   5,   7,   5,   5,   4,   255, 255, 255, 255,
+        255, 255, 255, 7,   255, 255, 255, 7,   255, 7,   7,   6,   255, 255,
+        255, 7,   255, 7,   7,   6,   255, 7,   7,   6,   7,   6,   6,   4,
+        255, 255, 255, 7,   255, 7,   7,   6,   255, 7,   7,   6,   7,   6,
+        6,   5,   255, 7,   7,   6,   7,   6,   6,   5,   7,   6,   6,   5,
+        6,   5,   5,   4,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 5,   255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 6,   255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 6,
+        255, 255, 255, 255, 255, 255, 255, 6,   255, 255, 255, 6,   255, 6,
+        6,   5,   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 7,   255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 7,   255, 255, 255, 255, 255, 255,
+        255, 7,   255, 255, 255, 7,   255, 7,   7,   5,   255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 7,   255, 255,
+        255, 255, 255, 255, 255, 7,   255, 255, 255, 7,   255, 7,   7,   6,
+        255, 255, 255, 255, 255, 255, 255, 7,   255, 255, 255, 7,   255, 7,
+        7,   6,   255, 255, 255, 7,   255, 7,   7,   6,   255, 7,   7,   6,
+        7,   6,   6,   5,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 6,   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 7,   255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 7,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 7,   255, 255, 255, 255, 255, 255, 255, 7,   255, 255, 255, 7,
+        255, 7,   7,   6,
+    },
+    {
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+        255, 255, 255, 7,
+    }};
+
+uint32 nth_bit(uint64 v, uint32 r) {
+  // nth_bit uses 1-origin for r, but code below is more natural with 0-origin.
+  r--;
+  uint32 next_v = v & 255;
+  uint32 v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 8) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 8 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 16) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 16 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 24) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 24 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 32) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 32 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 40) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 40 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 48) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 48 + nth_bit_bit_pos[r][next_v];
+  r -= v_in_byte;
+  next_v = (v >> 56) & 255;
+  v_in_byte = nth_bit_bit_count[next_v];
+  if (r < v_in_byte) return 56 + nth_bit_bit_pos[r][next_v];
+  return -1;
+}
+
+#elif !defined(__BMI2__)
+// This table is generated using:
 //
 //  for (size_t i = 0; i < 256; ++i) {
 //    uint32 offsets = 0;
@@ -71,4 +309,4 @@ const uint32 nth_bit_bit_offset[] = {
     0x88765421, 0x87654210, 0x88876543, 0x88765430, 0x88765431, 0x87654310,
     0x88765432, 0x87654320, 0x87654321, 0x76543210,
 };
-#endif  // !defined(__BMI2__)
+#endif  // !defined(__BMI2__) && !defined(__arm__)
index 5ede45b..3b98616 100644 (file)
@@ -8,23 +8,23 @@ LDADD = libfstpdtscript.la \
         ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
 
-pdtcompose_SOURCES = pdtcompose.cc
+pdtcompose_SOURCES = pdtcompose.cc pdtcompose-main.cc
 
-pdtexpand_SOURCES = pdtexpand.cc
+pdtexpand_SOURCES = pdtexpand.cc pdtexpand-main.cc
 
-pdtinfo_SOURCES = pdtinfo.cc
+pdtinfo_SOURCES = pdtinfo.cc pdtinfo-main.cc
 
-pdtreplace_SOURCES = pdtreplace.cc
+pdtreplace_SOURCES = pdtreplace.cc pdtreplace-main.cc
 
-pdtreverse_SOURCES = pdtreverse.cc
+pdtreverse_SOURCES = pdtreverse.cc pdtreverse-main.cc
 
-pdtshortestpath_SOURCES = pdtshortestpath.cc
+pdtshortestpath_SOURCES = pdtshortestpath.cc pdtshortestpath-main.cc
 endif
 
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstpdtscript.la
 libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-libfstpdtscript_la_LDFLAGS = -version-info 16:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 17:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 243db7f..ea769f9 100644 (file)
@@ -153,43 +153,50 @@ libfstpdtscript_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @HAVE_SCRIPT_TRUE@am_libfstpdtscript_la_rpath = -rpath $(libdir)
 PROGRAMS = $(bin_PROGRAMS)
-am__pdtcompose_SOURCES_DIST = pdtcompose.cc
-@HAVE_BIN_TRUE@am_pdtcompose_OBJECTS = pdtcompose.$(OBJEXT)
+am__pdtcompose_SOURCES_DIST = pdtcompose.cc pdtcompose-main.cc
+@HAVE_BIN_TRUE@am_pdtcompose_OBJECTS = pdtcompose.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtcompose-main.$(OBJEXT)
 pdtcompose_OBJECTS = $(am_pdtcompose_OBJECTS)
 pdtcompose_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtcompose_DEPENDENCIES = libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__pdtexpand_SOURCES_DIST = pdtexpand.cc
-@HAVE_BIN_TRUE@am_pdtexpand_OBJECTS = pdtexpand.$(OBJEXT)
+am__pdtexpand_SOURCES_DIST = pdtexpand.cc pdtexpand-main.cc
+@HAVE_BIN_TRUE@am_pdtexpand_OBJECTS = pdtexpand.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtexpand-main.$(OBJEXT)
 pdtexpand_OBJECTS = $(am_pdtexpand_OBJECTS)
 pdtexpand_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtexpand_DEPENDENCIES = libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__pdtinfo_SOURCES_DIST = pdtinfo.cc
-@HAVE_BIN_TRUE@am_pdtinfo_OBJECTS = pdtinfo.$(OBJEXT)
+am__pdtinfo_SOURCES_DIST = pdtinfo.cc pdtinfo-main.cc
+@HAVE_BIN_TRUE@am_pdtinfo_OBJECTS = pdtinfo.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtinfo-main.$(OBJEXT)
 pdtinfo_OBJECTS = $(am_pdtinfo_OBJECTS)
 pdtinfo_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtinfo_DEPENDENCIES = libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__pdtreplace_SOURCES_DIST = pdtreplace.cc
-@HAVE_BIN_TRUE@am_pdtreplace_OBJECTS = pdtreplace.$(OBJEXT)
+am__pdtreplace_SOURCES_DIST = pdtreplace.cc pdtreplace-main.cc
+@HAVE_BIN_TRUE@am_pdtreplace_OBJECTS = pdtreplace.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtreplace-main.$(OBJEXT)
 pdtreplace_OBJECTS = $(am_pdtreplace_OBJECTS)
 pdtreplace_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtreplace_DEPENDENCIES = libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__pdtreverse_SOURCES_DIST = pdtreverse.cc
-@HAVE_BIN_TRUE@am_pdtreverse_OBJECTS = pdtreverse.$(OBJEXT)
+am__pdtreverse_SOURCES_DIST = pdtreverse.cc pdtreverse-main.cc
+@HAVE_BIN_TRUE@am_pdtreverse_OBJECTS = pdtreverse.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtreverse-main.$(OBJEXT)
 pdtreverse_OBJECTS = $(am_pdtreverse_OBJECTS)
 pdtreverse_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtreverse_DEPENDENCIES = libfstpdtscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la $(am__DEPENDENCIES_1)
-am__pdtshortestpath_SOURCES_DIST = pdtshortestpath.cc
-@HAVE_BIN_TRUE@am_pdtshortestpath_OBJECTS = pdtshortestpath.$(OBJEXT)
+am__pdtshortestpath_SOURCES_DIST = pdtshortestpath.cc \
+       pdtshortestpath-main.cc
+@HAVE_BIN_TRUE@am_pdtshortestpath_OBJECTS = pdtshortestpath.$(OBJEXT) \
+@HAVE_BIN_TRUE@        pdtshortestpath-main.$(OBJEXT)
 pdtshortestpath_OBJECTS = $(am_pdtshortestpath_OBJECTS)
 pdtshortestpath_LDADD = $(LDADD)
 @HAVE_BIN_TRUE@pdtshortestpath_DEPENDENCIES = libfstpdtscript.la \
@@ -405,15 +412,15 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
 
-@HAVE_BIN_TRUE@pdtcompose_SOURCES = pdtcompose.cc
-@HAVE_BIN_TRUE@pdtexpand_SOURCES = pdtexpand.cc
-@HAVE_BIN_TRUE@pdtinfo_SOURCES = pdtinfo.cc
-@HAVE_BIN_TRUE@pdtreplace_SOURCES = pdtreplace.cc
-@HAVE_BIN_TRUE@pdtreverse_SOURCES = pdtreverse.cc
-@HAVE_BIN_TRUE@pdtshortestpath_SOURCES = pdtshortestpath.cc
+@HAVE_BIN_TRUE@pdtcompose_SOURCES = pdtcompose.cc pdtcompose-main.cc
+@HAVE_BIN_TRUE@pdtexpand_SOURCES = pdtexpand.cc pdtexpand-main.cc
+@HAVE_BIN_TRUE@pdtinfo_SOURCES = pdtinfo.cc pdtinfo-main.cc
+@HAVE_BIN_TRUE@pdtreplace_SOURCES = pdtreplace.cc pdtreplace-main.cc
+@HAVE_BIN_TRUE@pdtreverse_SOURCES = pdtreverse.cc pdtreverse-main.cc
+@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 16:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 17:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
@@ -569,12 +576,18 @@ distclean-compile:
        -rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtcompose.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtexpand.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreplace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtreverse.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtscript.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath-main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdtshortestpath.Po@am__quote@
 
 .cc.o:
index e1c6877..2eb6856 100644 (file)
@@ -6,7 +6,7 @@
 namespace fst {
 namespace script {
 
-bool GetPdtComposeFilter(const string &str, PdtComposeFilter *cf) {
+bool GetPdtComposeFilter(const std::string &str, PdtComposeFilter *cf) {
   if (str == "expand") {
     *cf = EXPAND_FILTER;
   } else if (str == "expand_paren") {
@@ -19,7 +19,7 @@ bool GetPdtComposeFilter(const string &str, PdtComposeFilter *cf) {
   return true;
 }
 
-bool GetPdtParserType(const string &str, PdtParserType *pt) {
+bool GetPdtParserType(const std::string &str, PdtParserType *pt) {
   if (str == "left") {
     *pt = PDT_LEFT_PARSER;
   } else if (str == "left_sr") {
diff --git a/src/extensions/pdt/pdtcompose-main.cc b/src/extensions/pdt/pdtcompose-main.cc
new file mode 100644 (file)
index 0000000..4221e6a
--- /dev/null
@@ -0,0 +1,79 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Composes a PDT and an FST.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/pdt/getters.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+
+DECLARE_string(pdt_parentheses);
+DECLARE_bool(left_pdt);
+DECLARE_bool(connect);
+DECLARE_string(compose_filter);
+
+int pdtcompose_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::ReadLabelPairs;
+  using fst::PdtComposeFilter;
+  using fst::PdtComposeOptions;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+
+  std::string usage = "Compose a PDT and an FST.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt in.fst [out.pdt]\n";
+  usage += " in.fst in.pdt [out.pdt]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc < 3 || argc > 4) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
+  const std::string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
+  const std::string out_name =
+      argc > 3 && strcmp(argv[3], "-") != 0 ? argv[3] : "";
+
+  if (in1_name.empty() && in2_name.empty()) {
+    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
+    return 1;
+  }
+
+  std::unique_ptr<FstClass> ifst1(FstClass::Read(in1_name));
+  if (!ifst1) return 1;
+  std::unique_ptr<FstClass> ifst2(FstClass::Read(in2_name));
+  if (!ifst2) return 1;
+
+  if (FLAGS_pdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
+
+  VectorFstClass ofst(ifst1->ArcType());
+
+  PdtComposeFilter compose_filter;
+  if (!s::GetPdtComposeFilter(FLAGS_compose_filter, &compose_filter)) {
+    LOG(ERROR) << argv[0] << ": Unknown or unsupported compose filter type: "
+               << FLAGS_compose_filter;
+    return 1;
+  }
+
+  const PdtComposeOptions copts(FLAGS_connect, compose_filter);
+
+  s::PdtCompose(*ifst1, *ifst2, parens, &ofst, copts, FLAGS_left_pdt);
+
+  return !ofst.Write(out_name);
+}
index a6cdb38..4b5816d 100644 (file)
@@ -3,18 +3,7 @@
 //
 // Composes a PDT and an FST.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/pdt/getters.h>
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
 
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 DEFINE_bool(left_pdt, true, "Is the first argument the PDT?");
@@ -23,62 +12,6 @@ DEFINE_string(compose_filter, "paren",
               "Composition filter, one of: \"expand\", \"expand_paren\", "
               "\"paren\"");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::ReadLabelPairs;
-  using fst::PdtComposeFilter;
-  using fst::PdtComposeOptions;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-
-  string usage = "Compose a PDT and an FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt in.fst [out.pdt]\n";
-  usage += " in.fst in.pdt [out.pdt]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc < 3 || argc > 4) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in1_name = strcmp(argv[1], "-") == 0 ? "" : argv[1];
-  const string in2_name = strcmp(argv[2], "-") == 0 ? "" : argv[2];
-  const string out_name = argc > 3 ? argv[3] : "";
-
-  if (in1_name.empty() && in2_name.empty()) {
-    LOG(ERROR) << argv[0] << ": Can't take both inputs from standard input.";
-    return 1;
-  }
-
-  std::unique_ptr<FstClass> ifst1(FstClass::Read(in1_name));
-  if (!ifst1) return 1;
-  std::unique_ptr<FstClass> ifst2(FstClass::Read(in2_name));
-  if (!ifst2) return 1;
-
-  if (FLAGS_pdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
-
-  VectorFstClass ofst(ifst1->ArcType());
-
-  PdtComposeFilter compose_filter;
-  if (!s::GetPdtComposeFilter(FLAGS_compose_filter, &compose_filter)) {
-    LOG(ERROR) << argv[0] << ": Unknown or unsupported compose filter type: "
-               << FLAGS_compose_filter;
-    return 1;
-  }
-
-  const PdtComposeOptions copts(FLAGS_connect, compose_filter);
-
-  s::PdtCompose(*ifst1, *ifst2, parens, &ofst, copts, FLAGS_left_pdt);
-
-  ofst.Write(out_name);
+int pdtcompose_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtcompose_main(argc, argv); }
diff --git a/src/extensions/pdt/pdtexpand-main.cc b/src/extensions/pdt/pdtexpand-main.cc
new file mode 100644 (file)
index 0000000..7085b0a
--- /dev/null
@@ -0,0 +1,65 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Expands a (bounded-stack) PDT as an FST.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+
+DECLARE_string(pdt_parentheses);
+DECLARE_bool(connect);
+DECLARE_bool(keep_parentheses);
+DECLARE_string(weight);
+
+int pdtexpand_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+  using fst::script::WeightClass;
+  using fst::ReadLabelPairs;
+
+  std::string usage = "Expand a (bounded-stack) PDT as an FST.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+  if (!ifst) return 1;
+
+  if (FLAGS_pdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
+
+  const auto weight_threshold =
+      FLAGS_weight.empty() ? WeightClass::Zero(ifst->WeightType())
+                           : WeightClass(ifst->WeightType(), FLAGS_weight);
+
+  VectorFstClass ofst(ifst->ArcType());
+  s::PdtExpand(*ifst, parens, &ofst,
+               s::PdtExpandOptions(FLAGS_connect, FLAGS_keep_parentheses,
+                                   weight_threshold));
+
+  return !ofst.Write(out_name);
+}
index f605dc8..44441d0 100644 (file)
@@ -3,66 +3,13 @@
 //
 // Expands a (bounded-stack) PDT as an FST.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
 
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 DEFINE_bool(connect, true, "Trim output?");
 DEFINE_bool(keep_parentheses, false, "Keep PDT parentheses in result?");
 DEFINE_string(weight, "", "Weight threshold");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-  using fst::script::WeightClass;
-  using fst::ReadLabelPairs;
-
-  string usage = "Expand a (bounded-stack) PDT as an FST.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
-
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
-
-  if (FLAGS_pdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
-
-  const auto weight_threshold =
-      FLAGS_weight.empty() ? WeightClass::Zero(ifst->WeightType())
-                           : WeightClass(ifst->WeightType(), FLAGS_weight);
-
-  VectorFstClass ofst(ifst->ArcType());
-  s::PdtExpand(*ifst, parens, &ofst,
-               s::PdtExpandOptions(FLAGS_connect, FLAGS_keep_parentheses,
-                                   weight_threshold));
-
-  ofst.Write(out_name);
+int pdtexpand_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtexpand_main(argc, argv); }
diff --git a/src/extensions/pdt/pdtinfo-main.cc b/src/extensions/pdt/pdtinfo-main.cc
new file mode 100644 (file)
index 0000000..7f0ce2e
--- /dev/null
@@ -0,0 +1,52 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Prints out various information about a PDT such as number of states, arcs,
+// and parentheses.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+
+DECLARE_string(pdt_parentheses);
+
+int pdtinfo_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::ReadLabelPairs;
+  using fst::script::FstClass;
+
+  std::string usage = "Prints out information about a PDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 2) {
+    ShowUsage();
+    return 1;
+  }
+
+  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_pdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
+
+  s::PrintPdtInfo(*ifst, parens);
+
+  return 0;
+}
index ca32150..59ef38c 100644 (file)
@@ -4,51 +4,10 @@
 // Prints out various information about a PDT such as number of states, arcs,
 // and parentheses.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
 
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::ReadLabelPairs;
-  using fst::script::FstClass;
-
-  string usage = "Prints out information about a PDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 2) {
-    ShowUsage();
-    return 1;
-  }
-
-  const 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_pdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
-
-  s::PrintPdtInfo(*ifst, parens);
+int pdtinfo_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtinfo_main(argc, argv); }
diff --git a/src/extensions/pdt/pdtreplace-main.cc b/src/extensions/pdt/pdtreplace-main.cc
new file mode 100644 (file)
index 0000000..cd6f0fc
--- /dev/null
@@ -0,0 +1,98 @@
+// 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 <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/extensions/pdt/getters.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+#include <fst/vector-fst.h>
+
+DECLARE_string(pdt_parentheses);
+DECLARE_string(pdt_parser_type);
+DECLARE_int64(start_paren_labels);
+DECLARE_string(left_paren_prefix);
+DECLARE_string(right_paren_prefix);
+
+namespace fst {
+namespace script {
+
+void Cleanup(std::vector<LabelFstClassPair> *pairs) {
+  for (const auto &pair : *pairs) {
+    delete pair.second;
+  }
+  pairs->clear();
+}
+
+}  // namespace script
+}  // namespace fst
+
+int pdtreplace_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+  using fst::PdtParserType;
+  using fst::WriteLabelPairs;
+
+  std::string usage = "Converts an RTN represented by FSTs";
+  usage += " and non-terminal labels into PDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " root.fst rootlabel [rule1.fst label1 ...] [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc < 4) {
+    ShowUsage();
+    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<s::LabelFstClassPair> 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;
+    }
+    // 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);
+  }
+
+  VectorFstClass ofst(ifst->ArcType());
+  std::vector<s::LabelPair> parens;
+  s::PdtReplace(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;
+  }
+
+  return !ofst.Write(out_name);
+}
index 7a5f47d..1237c64 100644 (file)
@@ -3,17 +3,8 @@
 //
 // Converts an RTN represented by FSTs and non-terminal labels into a PDT.
 
-#include <cstring>
-
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-
-#include <fst/extensions/pdt/getters.h>
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
-#include <fst/vector-fst.h>
+#include <fst/fst.h>
 
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 DEFINE_string(pdt_parser_type, "left",
@@ -27,76 +18,6 @@ DEFINE_string(left_paren_prefix, "(_", "Prefix to attach to SymbolTable "
 DEFINE_string(right_paren_prefix, ")_", "Prefix to attach to SymbolTable "
               "labels for inserted right parentheses");
 
-void Cleanup(std::vector<fst::script::LabelFstClassPair> *pairs) {
-  for (const auto &pair : *pairs) {
-    delete pair.second;
-  }
-  pairs->clear();
-}
-
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-  using fst::PdtParserType;
-  using fst::WriteLabelPairs;
-
-  string usage = "Converts an RTN represented by FSTs";
-  usage += " and non-terminal labels into PDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " root.fst rootlabel [rule1.fst label1 ...] [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc < 4) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name = argv[1];
-  const 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<s::LabelFstClassPair> 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) {
-      Cleanup(&pairs);
-      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);
-  }
-
-  VectorFstClass ofst(ifst->ArcType());
-  std::vector<s::LabelPair> parens;
-  s::PdtReplace(pairs, &ofst, &parens, root, parser_type,
-                FLAGS_start_paren_labels, FLAGS_left_paren_prefix,
-                FLAGS_right_paren_prefix);
-  Cleanup(&pairs);
-
-  if (!FLAGS_pdt_parentheses.empty()) {
-    if (!WriteLabelPairs(FLAGS_pdt_parentheses, parens)) return 1;
-  }
-
-  ofst.Write(out_name);
+int pdtreplace_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtreplace_main(argc, argv); }
diff --git a/src/extensions/pdt/pdtreverse-main.cc b/src/extensions/pdt/pdtreverse-main.cc
new file mode 100644 (file)
index 0000000..1167bdc
--- /dev/null
@@ -0,0 +1,56 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Reverses a PDT.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+
+DECLARE_string(pdt_parentheses);
+
+int pdtreverse_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::ReadLabelPairs;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+
+  std::string usage = "Reverse a PDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+  if (!ifst) return 1;
+
+  if (FLAGS_pdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
+
+  VectorFstClass ofst(ifst->ArcType());
+
+  s::PdtReverse(*ifst, parens, &ofst);
+
+  return !ofst.Write(out_name);
+}
index 042f757..9ec4fa5 100644 (file)
@@ -3,57 +3,10 @@
 //
 // Reverses a PDT.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
 
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::ReadLabelPairs;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-
-  string usage = "Reverse a PDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
-
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
-
-  if (FLAGS_pdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
-
-  VectorFstClass ofst(ifst->ArcType());
-
-  s::PdtReverse(*ifst, parens, &ofst);
-
-  ofst.Write(out_name);
+int pdtreverse_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtreverse_main(argc, argv); }
index 64da244..9881834 100644 (file)
@@ -7,12 +7,13 @@
 // See comments in nlp/fst/script/script-impl.h for how the registration
 // mechanism allows these to work with various arc types.
 
+#include <fst/extensions/pdt/pdtscript.h>
+
 #include <string>
 #include <vector>
 
 #include <fst/extensions/pdt/compose.h>
 #include <fst/extensions/pdt/expand.h>
-#include <fst/extensions/pdt/pdtscript.h>
 #include <fst/extensions/pdt/replace.h>
 #include <fst/extensions/pdt/reverse.h>
 #include <fst/extensions/pdt/shortest-path.h>
@@ -50,8 +51,8 @@ void PdtExpand(const FstClass &ifst,
 void PdtReplace(const std::vector<LabelFstClassPair> &pairs,
                 MutableFstClass *ofst, std::vector<LabelPair> *parens,
                 int64 root, PdtParserType parser_type, int64 start_paren_labels,
-                const string &left_paren_prefix,
-                const string &right_paren_prefix) {
+                const std::string &left_paren_prefix,
+                const std::string &right_paren_prefix) {
   for (size_t i = 1; i < pairs.size(); ++i) {
     if (!internal::ArcTypesMatch(*pairs[i - 1].second, *pairs[i].second,
                                  "PdtReplace"))
diff --git a/src/extensions/pdt/pdtshortestpath-main.cc b/src/extensions/pdt/pdtshortestpath-main.cc
new file mode 100644 (file)
index 0000000..2d3a4b1
--- /dev/null
@@ -0,0 +1,75 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Returns the shortest path in a (bounded-stack) PDT.
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <fst/flags.h>
+#include <fst/log.h>
+#include <fst/extensions/pdt/pdtscript.h>
+#include <fst/util.h>
+
+DECLARE_bool(keep_parentheses);
+DECLARE_string(queue_type);
+DECLARE_bool(path_gc);
+DECLARE_string(pdt_parentheses);
+
+int pdtshortestpath_main(int argc, char **argv) {
+  namespace s = fst::script;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
+  using fst::QueueType;
+  using fst::ReadLabelPairs;
+
+  std::string usage = "Shortest path in a (bounded-stack) PDT.\n\n  Usage: ";
+  usage += argv[0];
+  usage += " in.pdt [out.fst]\n";
+
+  std::set_new_handler(FailedNewHandler);
+  SET_FLAGS(usage.c_str(), &argc, &argv, true);
+  if (argc > 3) {
+    ShowUsage();
+    return 1;
+  }
+
+  const std::string in_name =
+      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
+  const std::string out_name =
+      (argc > 2 && (strcmp(argv[2], "-") != 0)) ? argv[2] : "";
+
+  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
+  if (!ifst) return 1;
+
+  if (FLAGS_pdt_parentheses.empty()) {
+    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
+    return 1;
+  }
+
+  std::vector<s::LabelPair> parens;
+  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
+
+  VectorFstClass ofst(ifst->ArcType());
+
+  QueueType qt;
+  if (FLAGS_queue_type == "fifo") {
+    qt = fst::FIFO_QUEUE;
+  } else if (FLAGS_queue_type == "lifo") {
+    qt = fst::LIFO_QUEUE;
+  } else if (FLAGS_queue_type == "state") {
+    qt = fst::STATE_ORDER_QUEUE;
+  } else {
+    LOG(ERROR) << "Unknown queue type: " << FLAGS_queue_type;
+    return 1;
+  }
+
+  const s::PdtShortestPathOptions opts(qt, FLAGS_keep_parentheses,
+                                       FLAGS_path_gc);
+
+  s::PdtShortestPath(*ifst, parens, &ofst, opts);
+
+  return !ofst.Write(out_name);
+}
index a7956b0..61ba8ff 100644 (file)
@@ -3,17 +3,7 @@
 //
 // Returns the shortest path in a (bounded-stack) PDT.
 
-#include <cstring>
-
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fst/flags.h>
-#include <fst/log.h>
-
-#include <fst/extensions/pdt/pdtscript.h>
-#include <fst/util.h>
 
 DEFINE_bool(keep_parentheses, false, "Keep PDT parentheses in result?");
 DEFINE_string(queue_type, "fifo",
@@ -22,59 +12,6 @@ DEFINE_string(queue_type, "fifo",
 DEFINE_bool(path_gc, true, "Garbage collect shortest path data?");
 DEFINE_string(pdt_parentheses, "", "PDT parenthesis label pairs");
 
-int main(int argc, char **argv) {
-  namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
-  using fst::QueueType;
-  using fst::ReadLabelPairs;
-
-  string usage = "Shortest path in a (bounded-stack) PDT.\n\n  Usage: ";
-  usage += argv[0];
-  usage += " in.pdt [out.fst]\n";
-
-  std::set_new_handler(FailedNewHandler);
-  SET_FLAGS(usage.c_str(), &argc, &argv, true);
-  if (argc > 3) {
-    ShowUsage();
-    return 1;
-  }
-
-  const string in_name =
-      (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
-  const string out_name = argc > 2 ? argv[2] : "";
-
-  std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
-  if (!ifst) return 1;
-
-  if (FLAGS_pdt_parentheses.empty()) {
-    LOG(ERROR) << argv[0] << ": No PDT parenthesis label pairs provided";
-    return 1;
-  }
-
-  std::vector<s::LabelPair> parens;
-  if (!ReadLabelPairs(FLAGS_pdt_parentheses, &parens, false)) return 1;
-
-  VectorFstClass ofst(ifst->ArcType());
-
-  QueueType qt;
-  if (FLAGS_queue_type == "fifo") {
-    qt = fst::FIFO_QUEUE;
-  } else if (FLAGS_queue_type == "lifo") {
-    qt = fst::LIFO_QUEUE;
-  } else if (FLAGS_queue_type == "state") {
-    qt = fst::STATE_ORDER_QUEUE;
-  } else {
-    LOG(ERROR) << "Unknown queue type: " << FLAGS_queue_type;
-    return 1;
-  }
-
-  const s::PdtShortestPathOptions opts(qt, FLAGS_keep_parentheses,
-                                       FLAGS_path_gc);
-
-  s::PdtShortestPath(*ifst, parens, &ofst, opts);
-
-  ofst.Write(out_name);
+int pdtshortestpath_main(int argc, char **argv);
 
-  return 0;
-}
+int main(int argc, char **argv) { return pdtshortestpath_main(argc, argv); }
index 0d93677..c3f8d86 100644 (file)
@@ -5,7 +5,7 @@
 from libc.stdint cimport *
 
 
-cdef extern from "<fst/types.h>" nogil:
+cdef extern from "base/integral_types.h" nogil:
 
   ctypedef int8_t int8
   ctypedef int16_t int16
index 51cef72..1763e43 100644 (file)
@@ -6,10 +6,10 @@ from libc.time cimport time_t
 from libc.time cimport time
 
 from libcpp cimport bool
+from libcpp.string cimport string
 from libcpp.vector cimport vector
 from libcpp.utility cimport pair
 
-from libcpp.string cimport string
 from basictypes cimport int32
 from basictypes cimport int64
 from basictypes cimport uint32
@@ -377,6 +377,8 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     int64 AddState()
 
+    void AddStates(size_t)
+
     bool DeleteArcs(int64, size_t)
 
     bool DeleteArcs(int64)
index be72573..b76b855 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.29.6 */
+/* Generated by Cython 0.29.12 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -7,8 +7,8 @@
 #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
     #error Cython requires Python 2.6+ or Python 3.3+.
 #else
-#define CYTHON_ABI "0_29_6"
-#define CYTHON_HEX_VERSION 0x001D06F0
+#define CYTHON_ABI "0_29_12"
+#define CYTHON_HEX_VERSION 0x001D0CF0
 #define CYTHON_FUTURE_DIVISION 1
 #include <stddef.h>
 #ifndef offsetof
@@ -324,8 +324,13 @@ class __Pyx_FakeReference {
   #define __Pyx_DefaultClassType PyClass_Type
 #else
   #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
+          PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#else
   #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
           PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+#endif
   #define __Pyx_DefaultClassType PyType_Type
 #endif
 #ifndef Py_TPFLAGS_CHECKTYPES
@@ -928,7 +933,7 @@ struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
 
-/* "fst.pxd":514
+/* "fst.pxd":516
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
@@ -937,7 +942,7 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
  */
 typedef std::pair<__pyx_t_10basictypes_int64,fst::script::FstClass const *>  __pyx_t_3fst_LabelFstClassPair;
 
-/* "fst.pxd":516
+/* "fst.pxd":518
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
@@ -1074,8 +1079,8 @@ struct __pyx_opt_args_9pywrapfst_4_Fst_text {
   PyObject *missing_sym;
 };
 
-/* "pywrapfst.pxd":289
- *   cpdef int64 add_state(self) except *
+/* "pywrapfst.pxd":291
+ *   cpdef void add_states(self, size_t) except *
  * 
  *   cdef void _arcsort(self, sort_type=?) except *             # <<<<<<<<<<<<<<
  * 
@@ -1086,7 +1091,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort {
   PyObject *sort_type;
 };
 
-/* "pywrapfst.pxd":291
+/* "pywrapfst.pxd":293
  *   cdef void _arcsort(self, sort_type=?) except *
  * 
  *   cdef void _closure(self, bool closure_plus=?) except *             # <<<<<<<<<<<<<<
@@ -1098,7 +1103,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure {
   bool closure_plus;
 };
 
-/* "pywrapfst.pxd":299
+/* "pywrapfst.pxd":301
  *   cdef void _decode(self, EncodeMapper) except *
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *             # <<<<<<<<<<<<<<
@@ -1110,7 +1115,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs {
   size_t n;
 };
 
-/* "pywrapfst.pxd":301
+/* "pywrapfst.pxd":303
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *
  * 
  *   cdef void _delete_states(self, states=?) except *             # <<<<<<<<<<<<<<
@@ -1122,7 +1127,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states {
   PyObject *states;
 };
 
-/* "pywrapfst.pxd":307
+/* "pywrapfst.pxd":309
  *   cdef void _invert(self) except *
  * 
  *   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *             # <<<<<<<<<<<<<<
@@ -1135,7 +1140,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize {
   bool allow_nondet;
 };
 
-/* "pywrapfst.pxd":313
+/* "pywrapfst.pxd":315
  *   cpdef int64 num_states(self)
  * 
  *   cdef void _project(self, bool project_output=?) except *             # <<<<<<<<<<<<<<
@@ -1147,7 +1152,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__project {
   bool project_output;
 };
 
-/* "pywrapfst.pxd":315
+/* "pywrapfst.pxd":317
  *   cdef void _project(self, bool project_output=?) except *
  * 
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *             # <<<<<<<<<<<<<<
@@ -1161,7 +1166,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":317
+/* "pywrapfst.pxd":319
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
  * 
  *   cdef void _push(self, float delta=?, bool remove_total_weight=?,             # <<<<<<<<<<<<<<
@@ -1175,7 +1180,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":320
+/* "pywrapfst.pxd":322
  *                   bool to_final=?) except *
  * 
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *             # <<<<<<<<<<<<<<
@@ -1188,7 +1193,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs {
   PyObject *opairs;
 };
 
-/* "pywrapfst.pxd":322
+/* "pywrapfst.pxd":324
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
  * 
  *   cdef void _relabel_tables(self, _SymbolTable old_isymbols=?,             # <<<<<<<<<<<<<<
@@ -1207,7 +1212,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables {
   bool attach_new_osymbols;
 };
 
-/* "pywrapfst.pxd":332
+/* "pywrapfst.pxd":334
  *   cdef void _reserve_states(self, int64 n) except *
  * 
  *   cdef void _reweight(self, potentials, bool to_final=?) except *             # <<<<<<<<<<<<<<
@@ -1219,7 +1224,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":334
+/* "pywrapfst.pxd":336
  *   cdef void _reweight(self, potentials, bool to_final=?) except *
  * 
  *   cdef void _rmepsilon(self, queue_type=?, bool connect=?, weight=?,             # <<<<<<<<<<<<<<
@@ -1235,7 +1240,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon {
   float delta;
 };
 
-/* "pywrapfst.pxd":337
+/* "pywrapfst.pxd":339
  *                        int64 nstate=?, float delta=?) except *
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
@@ -1247,7 +1252,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":361
+/* "pywrapfst.pxd":363
  * cdef _Fst _init_XFst(FstClass_ptr tfst)
  * 
  * cdef _MutableFst _create_Fst(arc_type=?)             # <<<<<<<<<<<<<<
@@ -1259,7 +1264,7 @@ struct __pyx_opt_args_9pywrapfst__create_Fst {
   PyObject *arc_type;
 };
 
-/* "pywrapfst.pxd":444
+/* "pywrapfst.pxd":446
  * 
  * 
  * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
@@ -1274,7 +1279,7 @@ struct __pyx_opt_args_9pywrapfst__map {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":446
+/* "pywrapfst.pxd":448
  * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
  * cpdef _Fst arcmap(_Fst ifst, float delta=?, map_type=?, double power=?,             # <<<<<<<<<<<<<<
@@ -1289,7 +1294,7 @@ struct __pyx_opt_args_9pywrapfst_arcmap {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":449
+/* "pywrapfst.pxd":451
  *                   weight=?)
  * 
  * cpdef _MutableFst compose(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
@@ -1302,7 +1307,7 @@ struct __pyx_opt_args_9pywrapfst_compose {
   bool connect;
 };
 
-/* "pywrapfst.pxd":452
+/* "pywrapfst.pxd":454
  *                           bool connect=?)
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
@@ -1314,7 +1319,7 @@ struct __pyx_opt_args_9pywrapfst_convert {
   PyObject *fst_type;
 };
 
-/* "pywrapfst.pxd":454
+/* "pywrapfst.pxd":456
  * cpdef _Fst convert(_Fst ifst, fst_type=?)
  * 
  * cpdef _MutableFst determinize(_Fst ifst, float delta=?, det_type=?,             # <<<<<<<<<<<<<<
@@ -1331,7 +1336,7 @@ struct __pyx_opt_args_9pywrapfst_determinize {
   bool increment_subsequential_label;
 };
 
-/* "pywrapfst.pxd":458
+/* "pywrapfst.pxd":460
  *                               weight=?, bool increment_subsequential_label=?)
  * 
  * cpdef _MutableFst difference(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
@@ -1344,7 +1349,7 @@ struct __pyx_opt_args_9pywrapfst_difference {
   bool connect;
 };
 
-/* "pywrapfst.pxd":461
+/* "pywrapfst.pxd":463
  *                              bool connect=?)
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst, float delta=?, int64 nstate=?,             # <<<<<<<<<<<<<<
@@ -1359,7 +1364,7 @@ struct __pyx_opt_args_9pywrapfst_disambiguate {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":464
+/* "pywrapfst.pxd":466
  *                                int64 subsequential_label=?, weight=?)
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
@@ -1371,7 +1376,7 @@ struct __pyx_opt_args_9pywrapfst_epsnormalize {
   bool eps_norm_output;
 };
 
-/* "pywrapfst.pxd":466
+/* "pywrapfst.pxd":468
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1383,7 +1388,7 @@ struct __pyx_opt_args_9pywrapfst_equal {
   float delta;
 };
 
-/* "pywrapfst.pxd":468
+/* "pywrapfst.pxd":470
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
@@ -1395,7 +1400,7 @@ struct __pyx_opt_args_9pywrapfst_equivalent {
   float delta;
 };
 
-/* "pywrapfst.pxd":470
+/* "pywrapfst.pxd":472
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
  * 
  * cpdef _MutableFst intersect(_Fst ifst1, _Fst ifst2, compose_filter=?,             # <<<<<<<<<<<<<<
@@ -1408,7 +1413,7 @@ struct __pyx_opt_args_9pywrapfst_intersect {
   bool connect;
 };
 
-/* "pywrapfst.pxd":473
+/* "pywrapfst.pxd":475
  *                             bool connect=?)
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1420,7 +1425,7 @@ struct __pyx_opt_args_9pywrapfst_isomorphic {
   float delta;
 };
 
-/* "pywrapfst.pxd":475
+/* "pywrapfst.pxd":477
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)
  * 
  * cpdef _MutableFst prune(_Fst ifst, float delta=?, int64 nstate=?,             # <<<<<<<<<<<<<<
@@ -1434,7 +1439,7 @@ struct __pyx_opt_args_9pywrapfst_prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":478
+/* "pywrapfst.pxd":480
  *                         weight=?)
  * 
  * cpdef _MutableFst push(_Fst ifst, float delta=?, bool push_weights=?,             # <<<<<<<<<<<<<<
@@ -1451,7 +1456,7 @@ struct __pyx_opt_args_9pywrapfst_push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":482
+/* "pywrapfst.pxd":484
  *                        bool remove_total_weight=?, bool to_final=?)
  * 
  * cpdef bool randequivalent(_Fst ifst1, _Fst ifst2, int32 npath=?,             # <<<<<<<<<<<<<<
@@ -1467,7 +1472,7 @@ struct __pyx_opt_args_9pywrapfst_randequivalent {
   __pyx_t_10basictypes_int32 max_length;
 };
 
-/* "pywrapfst.pxd":486
+/* "pywrapfst.pxd":488
  *                           int32 max_length=?) except *
  * 
  * cpdef _MutableFst randgen(_Fst ifst, int32 npath=?, time_t seed=?,             # <<<<<<<<<<<<<<
@@ -1484,7 +1489,7 @@ struct __pyx_opt_args_9pywrapfst_randgen {
   bool weighted;
 };
 
-/* "pywrapfst.pxd":493
+/* "pywrapfst.pxd":495
  *     bool epsilon_on_replace) except *
  * 
  * cpdef _MutableFst replace(pairs, call_arc_labeling=?, return_arc_labeling=?,             # <<<<<<<<<<<<<<
@@ -1499,7 +1504,7 @@ struct __pyx_opt_args_9pywrapfst_replace {
   __pyx_t_10basictypes_int64 return_label;
 };
 
-/* "pywrapfst.pxd":496
+/* "pywrapfst.pxd":498
  *                           bool epsilon_on_replace=?, int64 return_label=?)
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
@@ -1511,7 +1516,7 @@ struct __pyx_opt_args_9pywrapfst_reverse {
   bool require_superinitial;
 };
 
-/* "pywrapfst.pxd":498
+/* "pywrapfst.pxd":500
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst, float delta=?,             # <<<<<<<<<<<<<<
@@ -1526,7 +1531,7 @@ struct __pyx_opt_args_9pywrapfst__shortestdistance {
   bool reverse;
 };
 
-/* "pywrapfst.pxd":502
+/* "pywrapfst.pxd":504
  *                                                 bool reverse=?) except *
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst, float delta=?, int32 nshortest=?,             # <<<<<<<<<<<<<<
@@ -1691,7 +1696,7 @@ struct __pyx_obj_9pywrapfst__MutableFst {
 };
 
 
-/* "pywrapfst.pxd":371
+/* "pywrapfst.pxd":373
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -1705,7 +1710,7 @@ struct __pyx_obj_9pywrapfst_Arc {
 };
 
 
-/* "pywrapfst.pxd":381
+/* "pywrapfst.pxd":383
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1720,7 +1725,7 @@ struct __pyx_obj_9pywrapfst_ArcIterator {
 };
 
 
-/* "pywrapfst.pxd":403
+/* "pywrapfst.pxd":405
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1735,7 +1740,7 @@ struct __pyx_obj_9pywrapfst_MutableArcIterator {
 };
 
 
-/* "pywrapfst.pxd":427
+/* "pywrapfst.pxd":429
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -1750,7 +1755,7 @@ struct __pyx_obj_9pywrapfst_StateIterator {
 };
 
 
-/* "pywrapfst.pxd":514
+/* "pywrapfst.pxd":516
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -1774,7 +1779,7 @@ struct __pyx_obj_9pywrapfst_Compiler {
 };
 
 
-/* "pywrapfst.pxd":535
+/* "pywrapfst.pxd":537
  * # FarReader.
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -1788,7 +1793,7 @@ struct __pyx_obj_9pywrapfst_FarReader {
 };
 
 
-/* "pywrapfst.pxd":560
+/* "pywrapfst.pxd":562
  * # FarWriter.
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -1802,7 +1807,7 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 };
 
 
-/* "pywrapfst.pyx":3118
+/* "pywrapfst.pyx":3130
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -2016,6 +2021,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFst {
   void (*_check_mutating_imethod)(struct __pyx_obj_9pywrapfst__MutableFst *);
   void (*_add_arc)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_obj_9pywrapfst_Arc *);
   __pyx_t_10basictypes_int64 (*add_state)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch);
+  void (*add_states)(struct __pyx_obj_9pywrapfst__MutableFst *, size_t, int __pyx_skip_dispatch);
   void (*_arcsort)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args);
   void (*_closure)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args);
   void (*_concat)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *);
@@ -2048,7 +2054,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFst {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFst *__pyx_vtabptr_9pywrapfst__MutableFst;
 
 
-/* "pywrapfst.pyx":2920
+/* "pywrapfst.pyx":2932
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -2062,7 +2068,7 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":2987
+/* "pywrapfst.pyx":2999
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -2083,7 +2089,7 @@ struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
 
 
-/* "pywrapfst.pyx":3098
+/* "pywrapfst.pyx":3110
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -2105,7 +2111,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3218
+/* "pywrapfst.pyx":3230
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -2122,7 +2128,7 @@ struct __pyx_vtabstruct_9pywrapfst_StateIterator {
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
 
 
-/* "pywrapfst.pyx":4119
+/* "pywrapfst.pyx":4133
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -2137,7 +2143,7 @@ struct __pyx_vtabstruct_9pywrapfst_Compiler {
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4249
+/* "pywrapfst.pyx":4263
  * 
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -2159,7 +2165,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4396
+/* "pywrapfst.pyx":4410
  * 
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -2262,7 +2268,7 @@ static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObje
 #define __Pyx_PyFunction_FastCall(func, args, nargs)\
     __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
 #if 1 || PY_VERSION_HEX < 0x030600B1
-static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs);
+static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs);
 #else
 #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs)
 #endif
@@ -2897,6 +2903,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
 static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto*/
@@ -3273,6 +3280,7 @@ static const char __pyx_k_O_EPSILONS[] = "O_EPSILONS";
 static const char __pyx_k_TOP_SORTED[] = "TOP_SORTED";
 static const char __pyx_k_UNWEIGHTED[] = "UNWEIGHTED";
 static const char __pyx_k_ValueError[] = "ValueError";
+static const char __pyx_k_add_states[] = "add_states";
 static const char __pyx_k_add_symbol[] = "add_symbol";
 static const char __pyx_k_functional[] = "functional";
 static const char __pyx_k_max_length[] = "max_length";
@@ -3630,6 +3638,7 @@ static PyObject *__pyx_kp_b__10;
 static PyObject *__pyx_n_s_acceptor;
 static PyObject *__pyx_n_s_add;
 static PyObject *__pyx_n_s_add_state;
+static PyObject *__pyx_n_s_add_states;
 static PyObject *__pyx_n_s_add_symbol;
 static PyObject *__pyx_n_s_add_table;
 static PyObject *__pyx_n_s_allow_negative_labels;
@@ -3946,36 +3955,37 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_project_output); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_project_output); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_cls, PyObject *__pyx_v_arc_type); /* proto */
@@ -21973,7 +21983,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
  *     self._check_mutating_imethod()
  *     return result             # <<<<<<<<<<<<<<
  * 
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
+ *   cpdef void add_states(self, size_t n) except *:
  */
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
@@ -22041,6 +22051,166 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9
 /* "pywrapfst.pyx":1864
  *     return result
  * 
+ *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
+ *     """
+ *     add_states(self, n)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch) {
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  __Pyx_RefNannySetupContext("add_states", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
+    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+    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, 1864, __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_11_MutableFst_5add_states)) {
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1864, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_1);
+        __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
+        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
+          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+          if (likely(__pyx_t_5)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+            __Pyx_INCREF(__pyx_t_5);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_4, function);
+          }
+        }
+        __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, 1864, __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;
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        goto __pyx_L0;
+      }
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
+      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
+      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
+        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
+      }
+      #endif
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
+    }
+    #endif
+  }
+
+  /* "pywrapfst.pyx":1873
+ *       n: The number of states to add.
+ *     """
+ *     self._mfst.get().AddStates(n)             # <<<<<<<<<<<<<<
+ *     self._check_mutating_imethod()
+ * 
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
+    __PYX_ERR(0, 1873, __pyx_L1_error)
+  }
+  __pyx_v_self->_mfst.get()->AddStates(__pyx_v_n);
+
+  /* "pywrapfst.pyx":1874
+ *     """
+ *     self._mfst.get().AddStates(n)
+ *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
+ * 
+ *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
+    __PYX_ERR(0, 1874, __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, 1874, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1864
+ *     return result
+ * 
+ *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
+ *     """
+ *     add_states(self, n)
+ */
+
+  /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_4add_states[] = "\n    add_states(self, n)\n\n    Adds n new states to the FST.\n\n    Args:\n      n: The number of states to add.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
+  size_t __pyx_v_n;
+  PyObject *__pyx_r = 0;
+  __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, 1864, __pyx_L3_error)
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_4add_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((size_t)__pyx_v_n));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("add_states", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_f_9pywrapfst_11_MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1864, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1864, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1876
+ *     self._check_mutating_imethod()
+ * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
@@ -22064,27 +22234,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1866
+  /* "pywrapfst.pyx":1878
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):             # <<<<<<<<<<<<<<
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1866, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1878, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v_sort_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1867
+    /* "pywrapfst.pyx":1879
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))             # <<<<<<<<<<<<<<
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1867, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1879, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1867, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1879, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -22098,7 +22268,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_sort_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_sort_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1867, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1879, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -22114,14 +22284,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1867, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1879, __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, 1867, __pyx_L1_error)
+    __PYX_ERR(0, 1879, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1866
+    /* "pywrapfst.pyx":1878
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
  *     cdef fst.ArcSortType sort_type_enum
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):             # <<<<<<<<<<<<<<
@@ -22130,7 +22300,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1868
+  /* "pywrapfst.pyx":1880
  *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)             # <<<<<<<<<<<<<<
@@ -22139,11 +22309,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(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, 1868, __pyx_L1_error)
+    __PYX_ERR(0, 1880, __pyx_L1_error)
   }
   fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v_sort_type_enum);
 
-  /* "pywrapfst.pyx":1869
+  /* "pywrapfst.pyx":1881
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22152,12 +22322,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(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, 1869, __pyx_L1_error)
+    __PYX_ERR(0, 1881, __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, 1869, __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, 1881, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1864
- *     return result
+  /* "pywrapfst.pyx":1876
+ *     self._check_mutating_imethod()
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
  *     cdef fst.ArcSortType sort_type_enum
@@ -22177,7 +22347,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1871
+/* "pywrapfst.pyx":1883
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22186,9 +22356,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_4arcsort[] = "\n    arcsort(self, sort_type=\"ilabel\")\n\n    Sorts arcs leaving each state of the FST.\n\n    This operation destructively sorts arcs leaving each state using either\n    input or output labels.\n\n    Args:\n      sort_type: Either \"ilabel\" (sort arcs according to input labels) or\n          \"olabel\" (sort arcs according to output labels).\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: Unknown sort type.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_6arcsort[] = "\n    arcsort(self, sort_type=\"ilabel\")\n\n    Sorts arcs leaving each state of the FST.\n\n    This operation destructively sorts arcs leaving each state using either\n    input or output labels.\n\n    Args:\n      sort_type: Either \"ilabel\" (sort arcs according to input labels) or\n          \"olabel\" (sort arcs according to output labels).\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: Unknown sort type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_sort_type = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -22215,7 +22385,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5arcsort(PyObject *__pyx_v_se
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 1871, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 1883, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22229,26 +22399,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5arcsort(PyObject *__pyx_v_se
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1871, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1883, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_4arcsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_sort_type);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_6arcsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_sort_type);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort __pyx_t_1;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":1890
+  /* "pywrapfst.pyx":1902
  *       FstArgError: Unknown sort type.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -22257,13 +22427,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arcsort");
-    __PYX_ERR(0, 1890, __pyx_L1_error)
+    __PYX_ERR(0, 1902, __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, 1890, __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, 1902, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1891
+  /* "pywrapfst.pyx":1903
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -22275,7 +22445,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1871
+  /* "pywrapfst.pyx":1883
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22293,7 +22463,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1893
+/* "pywrapfst.pyx":1905
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22311,7 +22481,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1894
+  /* "pywrapfst.pyx":1906
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
@@ -22320,11 +22490,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(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, 1894, __pyx_L1_error)
+    __PYX_ERR(0, 1906, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":1895
+  /* "pywrapfst.pyx":1907
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22333,11 +22503,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(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, 1895, __pyx_L1_error)
+    __PYX_ERR(0, 1907, __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, 1895, __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, 1907, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1893
+  /* "pywrapfst.pyx":1905
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22353,7 +22523,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1897
+/* "pywrapfst.pyx":1909
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22362,9 +22532,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_6closure[] = "\n    closure(self, closure_plus=False)\n\n    Computes concatenative closure.\n\n    This operation destructively converts the FST to its concatenative closure.\n    If A transduces string x to y with weight a, then the closure transduces x\n    to y with weight a, xx to yy with weight a \\otimes a, xxx to yyy with weight\n    a \\otimes a \\otimes a, and so on. The empty string is also transduced to\n    itself with semiring One if `closure_plus` is False.\n\n    Args:\n      closure_plus: If False, do not accept the empty string.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_8closure[] = "\n    closure(self, closure_plus=False)\n\n    Computes concatenative closure.\n\n    This operation destructively converts the FST to its concatenative closure.\n    If A transduces string x to y with weight a, then the closure transduces x\n    to y with weight a, xx to yy with weight a \\otimes a, xxx to yyy with weight\n    a \\otimes a \\otimes a, and so on. The empty string is also transduced to\n    itself with semiring One if `closure_plus` is False.\n\n    Args:\n      closure_plus: If False, do not accept the empty string.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   bool __pyx_v_closure_plus;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -22390,7 +22560,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7closure(PyObject *__pyx_v_se
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 1897, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 1909, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22401,33 +22571,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7closure(PyObject *__pyx_v_se
       }
     }
     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, 1897, __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, 1909, __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, 1897, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1909, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_6closure(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_closure_plus);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_8closure(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_closure_plus);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure __pyx_t_1;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":1915
+  /* "pywrapfst.pyx":1927
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -22436,13 +22606,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_closure");
-    __PYX_ERR(0, 1915, __pyx_L1_error)
+    __PYX_ERR(0, 1927, __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); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1915, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_closure(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1927, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1916
+  /* "pywrapfst.pyx":1928
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
@@ -22454,7 +22624,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1897
+  /* "pywrapfst.pyx":1909
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22472,7 +22642,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1918
+/* "pywrapfst.pyx":1930
  *     return self
  * 
  *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -22484,7 +22654,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":1919
+  /* "pywrapfst.pyx":1931
  * 
  *   cdef void _concat(self, _Fst ifst) except *:
  *     fst.Concat(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
@@ -22493,15 +22663,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 1919, __pyx_L1_error)
+    __PYX_ERR(0, 1931, __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, 1919, __pyx_L1_error)
+    __PYX_ERR(0, 1931, __pyx_L1_error)
   }
   fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
 
-  /* "pywrapfst.pyx":1920
+  /* "pywrapfst.pyx":1932
  *   cdef void _concat(self, _Fst ifst) except *:
  *     fst.Concat(self._mfst.get(), deref(ifst._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22510,11 +22680,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 1920, __pyx_L1_error)
+    __PYX_ERR(0, 1932, __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, 1920, __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, 1932, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1918
+  /* "pywrapfst.pyx":1930
  *     return self
  * 
  *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -22530,7 +22700,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1922
+/* "pywrapfst.pyx":1934
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -22539,14 +22709,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_8concat[] = "\n    concat(self, ifst)\n\n    Computes the concatenation (product) of two FSTs.\n\n    This operation destructively concatenates the FST with a second FST. If A\n    transduces string x to y with weight a and B transduces string w to v with\n    weight b, then their concatenation transduces string xw to yv with weight a\n    \\otimes b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_10concat[] = "\n    concat(self, ifst)\n\n    Computes the concatenation (product) of two FSTs.\n\n    This operation destructively concatenates the FST with a second FST. If A\n    transduces string x to y with weight a and B transduces string w to v with\n    weight b, then their concatenation transduces string xw to yv with weight a\n    \\otimes b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 1922, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_8concat(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 1934, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_10concat(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
 
   /* function exit code */
   goto __pyx_L0;
@@ -22557,12 +22727,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9concat(PyObject *__pyx_v_sel
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":1939
+  /* "pywrapfst.pyx":1951
  *       self.
  *     """
  *     self._concat(ifst)             # <<<<<<<<<<<<<<
@@ -22571,11 +22741,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(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, 1939, __pyx_L1_error)
+    __PYX_ERR(0, 1951, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1939, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1951, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1940
+  /* "pywrapfst.pyx":1952
  *     """
  *     self._concat(ifst)
  *     return self             # <<<<<<<<<<<<<<
@@ -22587,7 +22757,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1922
+  /* "pywrapfst.pyx":1934
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -22605,7 +22775,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1942
+/* "pywrapfst.pyx":1954
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22617,7 +22787,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":1943
+  /* "pywrapfst.pyx":1955
  * 
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -22626,11 +22796,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(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, 1943, __pyx_L1_error)
+    __PYX_ERR(0, 1955, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":1944
+  /* "pywrapfst.pyx":1956
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22639,11 +22809,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(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, 1944, __pyx_L1_error)
+    __PYX_ERR(0, 1956, __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, 1944, __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, 1956, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1942
+  /* "pywrapfst.pyx":1954
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22659,7 +22829,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1946
+/* "pywrapfst.pyx":1958
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22668,25 +22838,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_10connect[] = "\n    connect(self)\n\n    Removes unsuccessful paths.\n\n    This operation destructively trims the FST, removing states and arcs that\n    are not part of any successful path.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_12connect[] = "\n    connect(self)\n\n    Removes unsuccessful paths.\n\n    This operation destructively trims the FST, removing states and arcs that\n    are not part of any successful path.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_10connect(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_12connect(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":1958
+  /* "pywrapfst.pyx":1970
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -22695,11 +22865,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_connect");
-    __PYX_ERR(0, 1958, __pyx_L1_error)
+    __PYX_ERR(0, 1970, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1958, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1970, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1959
+  /* "pywrapfst.pyx":1971
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
@@ -22711,7 +22881,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1946
+  /* "pywrapfst.pyx":1958
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22729,7 +22899,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1961
+/* "pywrapfst.pyx":1973
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -22741,7 +22911,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":1962
+  /* "pywrapfst.pyx":1974
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:
  *     fst.Decode(self._mfst.get(), deref(encoder._encoder))             # <<<<<<<<<<<<<<
@@ -22750,15 +22920,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 1962, __pyx_L1_error)
+    __PYX_ERR(0, 1974, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 1962, __pyx_L1_error)
+    __PYX_ERR(0, 1974, __pyx_L1_error)
   }
   fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_encoder->_encoder));
 
-  /* "pywrapfst.pyx":1963
+  /* "pywrapfst.pyx":1975
  *   cdef void _decode(self, EncodeMapper encoder) except *:
  *     fst.Decode(self._mfst.get(), deref(encoder._encoder))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22767,11 +22937,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 1963, __pyx_L1_error)
+    __PYX_ERR(0, 1975, __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, 1963, __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, 1975, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1961
+  /* "pywrapfst.pyx":1973
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -22787,7 +22957,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1965
+/* "pywrapfst.pyx":1977
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -22796,14 +22966,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_12decode[] = "\n    decode(self, encoder)\n\n    Decodes encoded labels and/or weights.\n\n    This operation reverses the encoding performed by `encode`.\n\n    Args:\n      encoder: An EncodeMapper object used to encode the FST.\n\n    Returns:\n      self.\n\n    See also: `encode`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_14decode[] = "\n    decode(self, encoder)\n\n    Decodes encoded labels and/or weights.\n\n    This operation reverses the encoding performed by `encode`.\n\n    Args:\n      encoder: An EncodeMapper object used to encode the FST.\n\n    Returns:\n      self.\n\n    See also: `encode`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 1965, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_12decode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 1977, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_14decode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
 
   /* function exit code */
   goto __pyx_L0;
@@ -22814,12 +22984,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13decode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":1981
+  /* "pywrapfst.pyx":1993
  *     See also: `encode`.
  *     """
  *     self._decode(encoder)             # <<<<<<<<<<<<<<
@@ -22828,11 +22998,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_decode");
-    __PYX_ERR(0, 1981, __pyx_L1_error)
+    __PYX_ERR(0, 1993, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1981, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1993, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1982
+  /* "pywrapfst.pyx":1994
  *     """
  *     self._decode(encoder)
  *     return self             # <<<<<<<<<<<<<<
@@ -22844,7 +23014,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1965
+  /* "pywrapfst.pyx":1977
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -22862,7 +23032,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1984
+/* "pywrapfst.pyx":1996
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -22885,7 +23055,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
   }
 
-  /* "pywrapfst.pyx":1985
+  /* "pywrapfst.pyx":1997
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22895,12 +23065,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   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, 1985, __pyx_L1_error)
+      __PYX_ERR(0, 1997, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":1986
+    /* "pywrapfst.pyx":1998
  *   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)):             # <<<<<<<<<<<<<<
@@ -22909,12 +23079,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 1986, __pyx_L1_error)
+      __PYX_ERR(0, 1998, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":1985
+  /* "pywrapfst.pyx":1997
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22924,14 +23094,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1987
+    /* "pywrapfst.pyx":1999
  *     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, 1987, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1999, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -22945,14 +23115,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
     __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, 1987, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1999, __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, 1987, __pyx_L1_error)
+    __PYX_ERR(0, 1999, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1985
+    /* "pywrapfst.pyx":1997
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22961,7 +23131,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1988
+  /* "pywrapfst.pyx":2000
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22970,11 +23140,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 1988, __pyx_L1_error)
+    __PYX_ERR(0, 2000, __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, 1988, __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, 2000, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1984
+  /* "pywrapfst.pyx":1996
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -22993,7 +23163,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1990
+/* "pywrapfst.pyx":2002
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -23002,9 +23172,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_14delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_states`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_states`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   size_t __pyx_v_n;
   PyObject *__pyx_r = 0;
@@ -23037,7 +23207,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15delete_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, 1990, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2002, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23048,35 +23218,35 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15delete_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1990, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2002, __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, 1990, __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, 2002, __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, 1990, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2002, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":2010
+  /* "pywrapfst.pyx":2022
  *     See also: `delete_states`.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -23085,13 +23255,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_arcs");
-    __PYX_ERR(0, 2010, __pyx_L1_error)
+    __PYX_ERR(0, 2022, __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, 2010, __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, 2022, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2011
+  /* "pywrapfst.pyx":2023
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -23103,7 +23273,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1990
+  /* "pywrapfst.pyx":2002
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -23121,7 +23291,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2013
+/* "pywrapfst.pyx":2025
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23144,17 +23314,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2015
+  /* "pywrapfst.pyx":2027
  *   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, 2015, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2027, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2016
+    /* "pywrapfst.pyx":2028
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23163,20 +23333,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 2016, __pyx_L1_error)
+      __PYX_ERR(0, 2028, __pyx_L1_error)
     }
-    __pyx_t_2 = __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2016, __pyx_L1_error)
+    __pyx_t_2 = __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2028, __pyx_L1_error)
     __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<__pyx_t_10basictypes_int64>  const )__pyx_t_2)) != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":2017
+      /* "pywrapfst.pyx":2029
  *     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, 2017, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2029, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_5 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -23190,14 +23360,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
       }
       __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, 2017, __pyx_L1_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2029, __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, 2017, __pyx_L1_error)
+      __PYX_ERR(0, 2029, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":2016
+      /* "pywrapfst.pyx":2028
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23206,7 +23376,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
     }
 
-    /* "pywrapfst.pyx":2015
+    /* "pywrapfst.pyx":2027
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -23216,7 +23386,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":2019
+  /* "pywrapfst.pyx":2031
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -23226,13 +23396,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2019, __pyx_L1_error)
+      __PYX_ERR(0, 2031, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":2020
+  /* "pywrapfst.pyx":2032
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23241,11 +23411,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(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, 2020, __pyx_L1_error)
+    __PYX_ERR(0, 2032, __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, 2020, __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, 2032, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2013
+  /* "pywrapfst.pyx":2025
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23264,7 +23434,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2022
+/* "pywrapfst.pyx":2034
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23273,9 +23443,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_16delete_states[] = "\n    delete_states(self, states=None)\n\n    Deletes states.\n\n    Args:\n      states: An optional iterable of integer indices of the states to be\n          deleted. If this argument is omitted, all states are deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_arcs`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_18delete_states[] = "\n    delete_states(self, states=None)\n\n    Deletes states.\n\n    Args:\n      states: An optional iterable of integer indices of the states to be\n          deleted. If this argument is omitted, all states are deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `delete_arcs`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_states = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -23302,7 +23472,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_states(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2022, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2034, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23316,26 +23486,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_states(PyObject *__p
   }
   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, 2022, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2034, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_16delete_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_states);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_18delete_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_states);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":2040
+  /* "pywrapfst.pyx":2052
  *     See also: `delete_arcs`.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
@@ -23344,13 +23514,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_states");
-    __PYX_ERR(0, 2040, __pyx_L1_error)
+    __PYX_ERR(0, 2052, __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, 2040, __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, 2052, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2041
+  /* "pywrapfst.pyx":2053
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
@@ -23362,7 +23532,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2022
+  /* "pywrapfst.pyx":2034
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23380,7 +23550,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2043
+/* "pywrapfst.pyx":2055
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -23392,7 +23562,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":2044
+  /* "pywrapfst.pyx":2056
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:
  *     fst.Encode(self._mfst.get(), encoder._encoder.get())             # <<<<<<<<<<<<<<
@@ -23401,15 +23571,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2044, __pyx_L1_error)
+    __PYX_ERR(0, 2056, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encoder");
-    __PYX_ERR(0, 2044, __pyx_L1_error)
+    __PYX_ERR(0, 2056, __pyx_L1_error)
   }
   fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_encoder->_encoder.get());
 
-  /* "pywrapfst.pyx":2045
+  /* "pywrapfst.pyx":2057
  *   cdef void _encode(self, EncodeMapper encoder) except *:
  *     fst.Encode(self._mfst.get(), encoder._encoder.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23418,11 +23588,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2045, __pyx_L1_error)
+    __PYX_ERR(0, 2057, __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, 2045, __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, 2057, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2043
+  /* "pywrapfst.pyx":2055
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -23438,7 +23608,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2047
+/* "pywrapfst.pyx":2059
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -23447,14 +23617,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_18encode[] = "\n    encode(self, encoder)\n\n    Encodes labels and/or weights.\n\n    This operation allows for the representation of a weighted transducer as a\n    weighted acceptor, an unweighted transducer, or an unweighted acceptor by\n    considering the pair (input label, output label), the pair (input label,\n    weight), or the triple (input label, output label, weight) as a single\n    label. Applying this operation mutates the EncodeMapper argument, which\n    can then be used to decode.\n\n    Args:\n      encoder: An EncodeMapper object to be used as the encoder.\n\n    Returns:\n      self.\n\n    See also: `decode`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_20encode[] = "\n    encode(self, encoder)\n\n    Encodes labels and/or weights.\n\n    This operation allows for the representation of a weighted transducer as a\n    weighted acceptor, an unweighted transducer, or an unweighted acceptor by\n    considering the pair (input label, output label), the pair (input label,\n    weight), or the triple (input label, output label, weight) as a single\n    label. Applying this operation mutates the EncodeMapper argument, which\n    can then be used to decode.\n\n    Args:\n      encoder: An EncodeMapper object to be used as the encoder.\n\n    Returns:\n      self.\n\n    See also: `decode`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_encoder) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 2047, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_18encode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 2059, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_20encode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_encoder));
 
   /* function exit code */
   goto __pyx_L0;
@@ -23465,12 +23635,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19encode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_encoder) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":2068
+  /* "pywrapfst.pyx":2080
  *     See also: `decode`.
  *     """
  *     self._encode(encoder)             # <<<<<<<<<<<<<<
@@ -23479,11 +23649,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encode");
-    __PYX_ERR(0, 2068, __pyx_L1_error)
+    __PYX_ERR(0, 2080, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2068, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_encoder); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2080, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2069
+  /* "pywrapfst.pyx":2081
  *     """
  *     self._encode(encoder)
  *     return self             # <<<<<<<<<<<<<<
@@ -23495,7 +23665,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2047
+  /* "pywrapfst.pyx":2059
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -23513,7 +23683,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2071
+/* "pywrapfst.pyx":2083
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23525,7 +23695,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":2072
+  /* "pywrapfst.pyx":2084
  * 
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -23534,11 +23704,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2072, __pyx_L1_error)
+    __PYX_ERR(0, 2084, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2073
+  /* "pywrapfst.pyx":2085
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23547,11 +23717,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(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, 2073, __pyx_L1_error)
+    __PYX_ERR(0, 2085, __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, 2073, __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, 2085, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2071
+  /* "pywrapfst.pyx":2083
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23567,7 +23737,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2075
+/* "pywrapfst.pyx":2087
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23576,25 +23746,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_20invert[] = "\n    invert(self)\n\n    Inverts the FST's transduction.\n\n    This operation destructively inverts the FST's transduction by exchanging\n    input and output labels.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_22invert[] = "\n    invert(self)\n\n    Inverts the FST's transduction.\n\n    This operation destructively inverts the FST's transduction by exchanging\n    input and output labels.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_20invert(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_22invert(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2087
+  /* "pywrapfst.pyx":2099
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -23603,11 +23773,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_invert");
-    __PYX_ERR(0, 2087, __pyx_L1_error)
+    __PYX_ERR(0, 2099, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2087, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2099, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2088
+  /* "pywrapfst.pyx":2100
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
@@ -23619,7 +23789,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2075
+  /* "pywrapfst.pyx":2087
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23637,7 +23807,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2090
+/* "pywrapfst.pyx":2102
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -23648,7 +23818,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
 static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize *__pyx_optional_args) {
   float __pyx_v_delta = __pyx_k__11;
 
-  /* "pywrapfst.pyx":2091
+  /* "pywrapfst.pyx":2103
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
@@ -23667,7 +23837,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2093
+  /* "pywrapfst.pyx":2105
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -23676,11 +23846,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(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, 2093, __pyx_L1_error)
+    __PYX_ERR(0, 2105, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2094
+  /* "pywrapfst.pyx":2106
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23689,11 +23859,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(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, 2094, __pyx_L1_error)
+    __PYX_ERR(0, 2106, __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, 2094, __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, 2106, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2090
+  /* "pywrapfst.pyx":2102
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -23709,7 +23879,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2096
+/* "pywrapfst.pyx":2108
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -23718,9 +23888,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_22minimize[] = "\n    minimize(self, delta=1e-6, allow_nondet=False)\n\n    Minimizes the FST.\n\n    This operation destructively performs the minimization of deterministic\n    weighted automata and transducers. If the input FST A is an acceptor, this\n    operation produces the minimal acceptor B equivalent to A, i.e. the\n    acceptor with a minimal number of states that is equivalent to A. If the\n    input FST A is a transducer, this operation internally builds an equivalent\n    transducer with a minimal number of states. However, this minimality is\n    obtained by allowing transition having strings of symbols as output labels,\n    this known in the litterature as a real-time transducer. Such transducers\n    are not directly supported by the library. This function will convert such\n    transducer by expanding each string-labeled transition into a sequence of\n    transitions. This will results in the creation of new states, hence losing\n    the minimality property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      allow_nondet: Attempt minimization of non-deterministic FST?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_24minimize[] = "\n    minimize(self, delta=1e-6, allow_nondet=False)\n\n    Minimizes the FST.\n\n    This operation destructively performs the minimization of deterministic\n    weighted automata and transducers. If the input FST A is an acceptor, this\n    operation produces the minimal acceptor B equivalent to A, i.e. the\n    acceptor with a minimal number of states that is equivalent to A. If the\n    input FST A is a transducer, this operation internally builds an equivalent\n    transducer with a minimal number of states. However, this minimality is\n    obtained by allowing transition having strings of symbols as output labels,\n    this known in the litterature as a real-time transducer. Such transducers\n    are not directly supported by the library. This function will convert such\n    transducer by expanding each string-labeled transition into a sequence of\n    transitions. This will results in the creation of new states, hence losing\n    the minimality property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      allow_nondet: Attempt minimization of non-deterministic FST?\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   bool __pyx_v_allow_nondet;
   PyObject *__pyx_r = 0;
@@ -23755,7 +23925,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23minimize(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2096, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2108, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23768,38 +23938,38 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23minimize(PyObject *__pyx_v_
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2096, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2108, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__12;
     }
     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, 2096, __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, 2108, __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, 2096, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2108, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_22minimize(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_allow_nondet);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_24minimize(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_allow_nondet);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize __pyx_t_1;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2122
+  /* "pywrapfst.pyx":2134
  *       self.
  *     """
  *     self._minimize(delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -23808,14 +23978,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_minimize");
-    __PYX_ERR(0, 2122, __pyx_L1_error)
+    __PYX_ERR(0, 2134, __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, 2122, __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, 2134, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2123
+  /* "pywrapfst.pyx":2135
  *     """
  *     self._minimize(delta, allow_nondet)
  *     return self             # <<<<<<<<<<<<<<
@@ -23827,7 +23997,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2096
+  /* "pywrapfst.pyx":2108
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -23845,7 +24015,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2125
+/* "pywrapfst.pyx":2137
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -23853,7 +24023,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
  *     mutable_arcs(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -23872,11 +24042,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     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, 2125, __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, 2137, __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_11_MutableFst_25mutable_arcs)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_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, 2125, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2137, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -23892,10 +24062,10 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
         __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, 2125, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2137, __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, 2125, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2137, __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;
@@ -23914,7 +24084,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     #endif
   }
 
-  /* "pywrapfst.pyx":2139
+  /* "pywrapfst.pyx":2151
  *     See also: `arcs`, `states`.
  *     """
  *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -23922,9 +24092,9 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
  *   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, 2139, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2139, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -23932,14 +24102,14 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
   __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, 2139, __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, 2151, __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_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2125
+  /* "pywrapfst.pyx":2137
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -23963,15 +24133,15 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_24mutable_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\n    See also: `arcs`, `states`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_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\n    See also: `arcs`, `states`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2125, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2137, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -23979,20 +24149,20 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25mutable_arcs(PyObject *__py
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("mutable_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2125, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2137, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -24009,7 +24179,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2141
+/* "pywrapfst.pyx":2153
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -24018,20 +24188,20 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_o
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_26mutable_input_symbols[] = "\n    mutable_input_symbols(self)\n\n    Returns the FST's (mutable) input symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_28mutable_input_symbols[] = "\n    mutable_input_symbols(self)\n\n    Returns the FST's (mutable) input symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_input_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   fst::SymbolTable *__pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -24039,7 +24209,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2147
+  /* "pywrapfst.pyx":2159
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()             # <<<<<<<<<<<<<<
@@ -24048,11 +24218,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2147, __pyx_L1_error)
+    __PYX_ERR(0, 2159, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableInputSymbols();
 
-  /* "pywrapfst.pyx":2148
+  /* "pywrapfst.pyx":2160
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24062,7 +24232,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2149
+    /* "pywrapfst.pyx":2161
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -24073,7 +24243,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2148
+    /* "pywrapfst.pyx":2160
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24082,7 +24252,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
  */
   }
 
-  /* "pywrapfst.pyx":2150
+  /* "pywrapfst.pyx":2162
  *     if syms == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
@@ -24092,15 +24262,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_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, 2150, __pyx_L1_error)
+    __PYX_ERR(0, 2162, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2150, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2162, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2141
+  /* "pywrapfst.pyx":2153
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -24119,7 +24289,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2152
+/* "pywrapfst.pyx":2164
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -24128,20 +24298,20 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_28mutable_output_symbols[] = "\n    mutable_output_symbols(self)\n\n    Returns the FST's (mutable) output symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_30mutable_output_symbols[] = "\n    mutable_output_symbols(self)\n\n    Returns the FST's (mutable) output symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_output_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   fst::SymbolTable *__pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -24149,7 +24319,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2158
+  /* "pywrapfst.pyx":2170
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
@@ -24158,11 +24328,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2158, __pyx_L1_error)
+    __PYX_ERR(0, 2170, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
 
-  /* "pywrapfst.pyx":2159
+  /* "pywrapfst.pyx":2171
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24172,7 +24342,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2160
+    /* "pywrapfst.pyx":2172
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -24183,7 +24353,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2159
+    /* "pywrapfst.pyx":2171
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
@@ -24192,7 +24362,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
  */
   }
 
-  /* "pywrapfst.pyx":2161
+  /* "pywrapfst.pyx":2173
  *     if syms == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
@@ -24202,15 +24372,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   __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, 2161, __pyx_L1_error)
+    __PYX_ERR(0, 2173, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2161, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2173, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2152
+  /* "pywrapfst.pyx":2164
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -24229,7 +24399,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2163
+/* "pywrapfst.pyx":2175
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -24237,7 +24407,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
  *     num_states(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch) {
   __pyx_t_10basictypes_int64 __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -24256,9 +24426,9 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(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_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2163, __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, 2175, __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_11_MutableFst_31num_states)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11_MutableFst_33num_states)) {
         __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))) {
@@ -24272,10 +24442,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(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, 2163, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2175, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2163, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2175, __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;
@@ -24294,7 +24464,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
     #endif
   }
 
-  /* "pywrapfst.pyx":2169
+  /* "pywrapfst.pyx":2181
  *     Returns the number of states.
  *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
@@ -24303,12 +24473,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2169, __pyx_L1_error)
+    __PYX_ERR(0, 2181, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2163
+  /* "pywrapfst.pyx":2175
  *     return _init_MutableFstSymbolTable(syms, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -24330,26 +24500,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_30num_states[] = "\n    num_states(self)\n\n    Returns the number of states.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_32num_states[] = "\n    num_states(self)\n\n    Returns the number of states.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_states (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_30num_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_32num_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("num_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_11_MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2163, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_11_MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2175, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -24366,7 +24536,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30num_states(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2171
+/* "pywrapfst.pyx":2183
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24384,7 +24554,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2172
+  /* "pywrapfst.pyx":2184
  * 
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))             # <<<<<<<<<<<<<<
@@ -24393,11 +24563,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(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, 2172, __pyx_L1_error)
+    __PYX_ERR(0, 2184, __pyx_L1_error)
   }
   fst::script::Project(__pyx_v_self->_mfst.get(), fst::script::GetProjectType(__pyx_v_project_output));
 
-  /* "pywrapfst.pyx":2173
+  /* "pywrapfst.pyx":2185
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24406,11 +24576,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(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, 2173, __pyx_L1_error)
+    __PYX_ERR(0, 2185, __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, 2173, __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, 2185, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2171
+  /* "pywrapfst.pyx":2183
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24426,7 +24596,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2175
+/* "pywrapfst.pyx":2187
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24435,9 +24605,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_32project[] = "\n    project(self, project_output=False)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_output: Should the output labels be projected?\n\n    Returns:\n      self.\n\n    See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_34project[] = "\n    project(self, project_output=False)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_output: Should the output labels be projected?\n\n    Returns:\n      self.\n\n    See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   bool __pyx_v_project_output;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -24463,7 +24633,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33project(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2175, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2187, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24474,33 +24644,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33project(PyObject *__pyx_v_s
       }
     }
     if (values[0]) {
-      __pyx_v_project_output = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_project_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2175, __pyx_L3_error)
+      __pyx_v_project_output = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_project_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2187, __pyx_L3_error)
     } else {
       __pyx_v_project_output = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("project", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2175, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("project", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2187, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_32project(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_project_output);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_34project(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_project_output);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_project_output) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_project_output) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__project __pyx_t_1;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2193
+  /* "pywrapfst.pyx":2205
  *     See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.
  *     """
  *     self._project(project_output)             # <<<<<<<<<<<<<<
@@ -24509,13 +24679,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_project");
-    __PYX_ERR(0, 2193, __pyx_L1_error)
+    __PYX_ERR(0, 2205, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.project_output = __pyx_v_project_output;
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2193, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2205, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2194
+  /* "pywrapfst.pyx":2206
  *     """
  *     self._project(project_output)
  *     return self             # <<<<<<<<<<<<<<
@@ -24527,7 +24697,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2175
+  /* "pywrapfst.pyx":2187
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24545,7 +24715,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2196
+/* "pywrapfst.pyx":2208
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24557,7 +24727,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
   float __pyx_v_delta = __pyx_k__13;
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__14;
 
-  /* "pywrapfst.pyx":2197
+  /* "pywrapfst.pyx":2209
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:             # <<<<<<<<<<<<<<
@@ -24581,7 +24751,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
     }
   }
 
-  /* "pywrapfst.pyx":2199
+  /* "pywrapfst.pyx":2211
  *                    weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -24590,20 +24760,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2199, __pyx_L1_error)
+    __PYX_ERR(0, 2211, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2200
+  /* "pywrapfst.pyx":2212
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)             # <<<<<<<<<<<<<<
  *     fst.Prune(self._mfst.get(), wc, 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, 2199, __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, 2211, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2201
+  /* "pywrapfst.pyx":2213
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -24612,11 +24782,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(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, 2201, __pyx_L1_error)
+    __PYX_ERR(0, 2213, __pyx_L1_error)
   }
   fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2202
+  /* "pywrapfst.pyx":2214
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24625,11 +24795,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(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, 2202, __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, 2202, __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":2196
+  /* "pywrapfst.pyx":2208
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24645,7 +24815,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2204
+/* "pywrapfst.pyx":2216
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24654,9 +24824,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_34prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n\n    See also: The constructive variant.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_36prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n\n    See also: The constructive variant.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   __pyx_t_10basictypes_int64 __pyx_v_nstate;
   PyObject *__pyx_v_weight = 0;
@@ -24667,7 +24837,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
     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":2207
+    /* "pywrapfst.pyx":2219
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -24709,7 +24879,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2204, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2216, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24724,12 +24894,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2205, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2217, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__15;
     }
     if (values[1]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2206, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2218, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__16;
     }
@@ -24737,15 +24907,15 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2204, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2216, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_34prune(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_36prune(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":2204
+  /* "pywrapfst.pyx":2216
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24758,13 +24928,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune __pyx_t_1;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2229
+  /* "pywrapfst.pyx":2241
  *     See also: The constructive variant.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -24773,15 +24943,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_prune");
-    __PYX_ERR(0, 2229, __pyx_L1_error)
+    __PYX_ERR(0, 2241, __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, 2229, __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, 2241, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2230
+  /* "pywrapfst.pyx":2242
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -24793,7 +24963,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2204
+  /* "pywrapfst.pyx":2216
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24811,7 +24981,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2232
+/* "pywrapfst.pyx":2244
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -24822,7 +24992,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
 static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__push *__pyx_optional_args) {
   float __pyx_v_delta = __pyx_k__17;
 
-  /* "pywrapfst.pyx":2234
+  /* "pywrapfst.pyx":2246
  *   cdef void _push(self,
  *                   float delta=fst.kDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -24831,7 +25001,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2235
+  /* "pywrapfst.pyx":2247
  *                   float delta=fst.kDelta,
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -24853,7 +25023,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
     }
   }
 
-  /* "pywrapfst.pyx":2236
+  /* "pywrapfst.pyx":2248
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,             # <<<<<<<<<<<<<<
@@ -24862,10 +25032,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(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, 2236, __pyx_L1_error)
+    __PYX_ERR(0, 2248, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2237
+  /* "pywrapfst.pyx":2249
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
@@ -24874,7 +25044,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
   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":2238
+  /* "pywrapfst.pyx":2250
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24883,11 +25053,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(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, 2238, __pyx_L1_error)
+    __PYX_ERR(0, 2250, __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, 2238, __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, 2250, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2232
+  /* "pywrapfst.pyx":2244
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -24903,7 +25073,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2240
+/* "pywrapfst.pyx":2252
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -24912,9 +25082,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_36push[] = "\n    push(self, delta=0.0009765625, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n\n    See also: The constructive variant, which also supports label pushing.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_38push[] = "\n    push(self, delta=0.0009765625, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n\n    See also: The constructive variant, which also supports label pushing.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   bool __pyx_v_remove_total_weight;
   bool __pyx_v_to_final;
@@ -24958,7 +25128,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(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, 2240, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2252, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24973,15 +25143,15 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(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, 2241, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2253, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__18;
     }
     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, 2242, __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, 2254, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2242
+      /* "pywrapfst.pyx":2254
  *   def push(self,
  *            float delta=fst.kDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -24991,10 +25161,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(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, 2243, __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, 2255, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2243
+      /* "pywrapfst.pyx":2255
  *            float delta=fst.kDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
@@ -25006,15 +25176,15 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(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, 2240, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2252, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_36push(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_38push(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":2240
+  /* "pywrapfst.pyx":2252
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -25027,13 +25197,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(PyObject *__pyx_v_self
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__push __pyx_t_1;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2269
+  /* "pywrapfst.pyx":2281
  *     See also: The constructive variant, which also supports label pushing.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
@@ -25042,15 +25212,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_push");
-    __PYX_ERR(0, 2269, __pyx_L1_error)
+    __PYX_ERR(0, 2281, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.remove_total_weight = __pyx_v_remove_total_weight;
   __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); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2269, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_push(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2281, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2270
+  /* "pywrapfst.pyx":2282
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -25062,7 +25232,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2240
+  /* "pywrapfst.pyx":2252
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -25080,7 +25250,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2272
+/* "pywrapfst.pyx":2284
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -25120,7 +25290,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2274
+  /* "pywrapfst.pyx":2286
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:
  *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
  *     _ipairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -25131,11 +25301,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     __pyx_t_1 = new std::vector<__pyx_t_3fst_LabelPair> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2274, __pyx_L1_error)
+    __PYX_ERR(0, 2286, __pyx_L1_error)
   }
   __pyx_v__ipairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2276
+  /* "pywrapfst.pyx":2288
  *     _ipairs.reset(new vector[fst.LabelPair]())
  *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
  *     _opairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -25146,21 +25316,21 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     __pyx_t_1 = new std::vector<__pyx_t_3fst_LabelPair> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2276, __pyx_L1_error)
+    __PYX_ERR(0, 2288, __pyx_L1_error)
   }
   __pyx_v__opairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2279
+  /* "pywrapfst.pyx":2291
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2279, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2291, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2280
+    /* "pywrapfst.pyx":2292
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -25171,26 +25341,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
       __pyx_t_3 = __pyx_v_ipairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
       __pyx_t_5 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2280, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2292, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2280, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2292, __pyx_L1_error)
     }
     for (;;) {
       if (likely(!__pyx_t_5)) {
         if (likely(PyList_CheckExact(__pyx_t_3))) {
           if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2280, __pyx_L1_error)
+          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2292, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2280, __pyx_L1_error)
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2292, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         } else {
           if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2280, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2292, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2280, __pyx_L1_error)
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2292, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25200,7 +25370,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2280, __pyx_L1_error)
+            else __PYX_ERR(0, 2292, __pyx_L1_error)
           }
           break;
         }
@@ -25212,7 +25382,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2280, __pyx_L1_error)
+          __PYX_ERR(0, 2292, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25225,15 +25395,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_INCREF(__pyx_t_7);
         __Pyx_INCREF(__pyx_t_8);
         #else
-        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2280, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2292, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2280, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2292, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         #endif
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2280, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2292, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
@@ -25241,7 +25411,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_GOTREF(__pyx_t_7);
         index = 1; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L6_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_8);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2280, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2292, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L7_unpacking_done;
@@ -25249,17 +25419,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_10 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2280, __pyx_L1_error)
+        __PYX_ERR(0, 2292, __pyx_L1_error)
         __pyx_L7_unpacking_done:;
       }
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2280, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2292, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2280, __pyx_L1_error)
+      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2292, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       __pyx_v_before = __pyx_t_11;
       __pyx_v_after = __pyx_t_12;
 
-      /* "pywrapfst.pyx":2281
+      /* "pywrapfst.pyx":2293
  *     if ipairs:
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -25270,16 +25440,16 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __pyx_t_13 = __pyx_t_3fst_LabelPair(__pyx_v_before, __pyx_v_after);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2281, __pyx_L1_error)
+        __PYX_ERR(0, 2293, __pyx_L1_error)
       }
       try {
         __pyx_v__ipairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2281, __pyx_L1_error)
+        __PYX_ERR(0, 2293, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2280
+      /* "pywrapfst.pyx":2292
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -25289,7 +25459,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2279
+    /* "pywrapfst.pyx":2291
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
@@ -25298,17 +25468,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2282
+  /* "pywrapfst.pyx":2294
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2282, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2294, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2283
+    /* "pywrapfst.pyx":2295
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25319,26 +25489,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
       __pyx_t_3 = __pyx_v_opairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
       __pyx_t_5 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2283, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2295, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2283, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2295, __pyx_L1_error)
     }
     for (;;) {
       if (likely(!__pyx_t_5)) {
         if (likely(PyList_CheckExact(__pyx_t_3))) {
           if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2283, __pyx_L1_error)
+          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2295, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2283, __pyx_L1_error)
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2295, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         } else {
           if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2283, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2295, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2283, __pyx_L1_error)
+          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2295, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25348,7 +25518,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2283, __pyx_L1_error)
+            else __PYX_ERR(0, 2295, __pyx_L1_error)
           }
           break;
         }
@@ -25360,7 +25530,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2283, __pyx_L1_error)
+          __PYX_ERR(0, 2295, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25373,15 +25543,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_INCREF(__pyx_t_8);
         __Pyx_INCREF(__pyx_t_7);
         #else
-        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2283, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2295, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2283, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2295, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         #endif
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2283, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2295, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
@@ -25389,7 +25559,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_GOTREF(__pyx_t_8);
         index = 1; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L11_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_7);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2283, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2295, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L12_unpacking_done;
@@ -25397,17 +25567,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_10 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2283, __pyx_L1_error)
+        __PYX_ERR(0, 2295, __pyx_L1_error)
         __pyx_L12_unpacking_done:;
       }
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2283, __pyx_L1_error)
+      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2295, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2283, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2295, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_v_before = __pyx_t_12;
       __pyx_v_after = __pyx_t_11;
 
-      /* "pywrapfst.pyx":2284
+      /* "pywrapfst.pyx":2296
  *     if opairs:
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -25418,16 +25588,16 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __pyx_t_13 = __pyx_t_3fst_LabelPair(__pyx_v_before, __pyx_v_after);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2284, __pyx_L1_error)
+        __PYX_ERR(0, 2296, __pyx_L1_error)
       }
       try {
         __pyx_v__opairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2284, __pyx_L1_error)
+        __PYX_ERR(0, 2296, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2283
+      /* "pywrapfst.pyx":2295
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25437,7 +25607,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2282
+    /* "pywrapfst.pyx":2294
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
@@ -25446,7 +25616,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2285
+  /* "pywrapfst.pyx":2297
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -25464,14 +25634,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __pyx_L14_bool_binop_done:;
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2286
+    /* "pywrapfst.pyx":2298
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():
  *       raise FstArgError("No relabeling pairs specified.")             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2286, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
@@ -25485,14 +25655,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_kp_u_No_relabeling_pairs_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_kp_u_No_relabeling_pairs_specified);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2286, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2286, __pyx_L1_error)
+    __PYX_ERR(0, 2298, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2285
+    /* "pywrapfst.pyx":2297
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -25501,7 +25671,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2287
+  /* "pywrapfst.pyx":2299
  *     if _ipairs.get().empty() and _opairs.get().empty():
  *       raise FstArgError("No relabeling pairs specified.")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))             # <<<<<<<<<<<<<<
@@ -25510,11 +25680,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(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, 2287, __pyx_L1_error)
+    __PYX_ERR(0, 2299, __pyx_L1_error)
   }
   fst::script::Relabel(__pyx_v_self->_mfst.get(), (*__pyx_v__ipairs), (*__pyx_v__opairs));
 
-  /* "pywrapfst.pyx":2288
+  /* "pywrapfst.pyx":2300
  *       raise FstArgError("No relabeling pairs specified.")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25523,11 +25693,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(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, 2288, __pyx_L1_error)
+    __PYX_ERR(0, 2300, __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, 2288, __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, 2300, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2272
+  /* "pywrapfst.pyx":2284
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -25548,7 +25718,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2290
+/* "pywrapfst.pyx":2302
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25557,9 +25727,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_38relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_tables`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_tables`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_ipairs = 0;
   PyObject *__pyx_v_opairs = 0;
   PyObject *__pyx_r = 0;
@@ -25596,7 +25766,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39relabel_pairs(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2290, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2302, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25613,26 +25783,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39relabel_pairs(PyObject *__p
   }
   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, 2290, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2302, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_ipairs, __pyx_v_opairs);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_ipairs, __pyx_v_opairs);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2312
+  /* "pywrapfst.pyx":2324
  *     See also: `decode`, `encode`, `project`, `relabel_tables`.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
@@ -25641,14 +25811,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_pairs");
-    __PYX_ERR(0, 2312, __pyx_L1_error)
+    __PYX_ERR(0, 2324, __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, 2312, __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, 2324, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2313
+  /* "pywrapfst.pyx":2325
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -25660,7 +25830,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2290
+  /* "pywrapfst.pyx":2302
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25678,7 +25848,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2315
+/* "pywrapfst.pyx":2327
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -25688,7 +25858,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
 
 static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":2316
+  /* "pywrapfst.pyx":2328
  * 
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25697,7 +25867,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":2317
+  /* "pywrapfst.pyx":2329
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,
  *                             _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25707,7 +25877,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
   PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_b__10);
 
-  /* "pywrapfst.pyx":2319
+  /* "pywrapfst.pyx":2331
  *                             _SymbolTable new_isymbols=None,
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -25716,7 +25886,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2320
+  /* "pywrapfst.pyx":2332
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25725,7 +25895,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":2321
+  /* "pywrapfst.pyx":2333
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,
  *                             _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25735,7 +25905,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
   PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_b__10);
 
-  /* "pywrapfst.pyx":2323
+  /* "pywrapfst.pyx":2335
  *                             _SymbolTable new_osymbols=None,
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
@@ -25785,7 +25955,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
   }
 
-  /* "pywrapfst.pyx":2324
+  /* "pywrapfst.pyx":2336
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -25805,14 +25975,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_L4_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2325
+    /* "pywrapfst.pyx":2337
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")             # <<<<<<<<<<<<<<
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2325, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2337, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -25826,14 +25996,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
     __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, 2325, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2337, __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, 2325, __pyx_L1_error)
+    __PYX_ERR(0, 2337, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2324
+    /* "pywrapfst.pyx":2336
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -25842,7 +26012,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2326
+  /* "pywrapfst.pyx":2338
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL             # <<<<<<<<<<<<<<
@@ -25851,7 +26021,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   __pyx_v_new_isymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":2327
+  /* "pywrapfst.pyx":2339
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -25862,7 +26032,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2328
+    /* "pywrapfst.pyx":2340
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:
  *       new_isymbols_ptr = new_isymbols._table             # <<<<<<<<<<<<<<
@@ -25871,12 +26041,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
     if (unlikely(((PyObject *)__pyx_v_new_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2328, __pyx_L1_error)
+      __PYX_ERR(0, 2340, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_new_isymbols->_table;
     __pyx_v_new_isymbols_ptr = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2327
+    /* "pywrapfst.pyx":2339
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -25885,7 +26055,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2329
+  /* "pywrapfst.pyx":2341
  *     if new_isymbols is not None:
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL             # <<<<<<<<<<<<<<
@@ -25894,7 +26064,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   __pyx_v_new_osymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":2330
+  /* "pywrapfst.pyx":2342
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -25905,7 +26075,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2331
+    /* "pywrapfst.pyx":2343
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table             # <<<<<<<<<<<<<<
@@ -25914,12 +26084,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
     if (unlikely(((PyObject *)__pyx_v_new_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2331, __pyx_L1_error)
+      __PYX_ERR(0, 2343, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_new_osymbols->_table;
     __pyx_v_new_osymbols_ptr = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2330
+    /* "pywrapfst.pyx":2342
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -25928,7 +26098,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2332
+  /* "pywrapfst.pyx":2344
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -25937,10 +26107,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2332, __pyx_L1_error)
+    __PYX_ERR(0, 2344, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2333
+  /* "pywrapfst.pyx":2345
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),
  *         self._fst.get().InputSymbols() if old_isymbols is None else             # <<<<<<<<<<<<<<
@@ -25951,12 +26121,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   if ((__pyx_t_1 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2333, __pyx_L1_error)
+      __PYX_ERR(0, 2345, __pyx_L1_error)
     }
     __pyx_t_8 = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":2334
+    /* "pywrapfst.pyx":2346
  *     fst.Relabel(self._mfst.get(),
  *         self._fst.get().InputSymbols() if old_isymbols is None else
  *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
@@ -25965,13 +26135,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
     if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2334, __pyx_L1_error)
+      __PYX_ERR(0, 2346, __pyx_L1_error)
     }
     __pyx_t_8 = __pyx_v_old_isymbols->_table;
   }
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2334, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2346, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2336
+  /* "pywrapfst.pyx":2348
  *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
  *         attach_new_isymbols,
  *         self._fst.get().OutputSymbols() if old_osymbols is None else             # <<<<<<<<<<<<<<
@@ -25982,12 +26152,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   if ((__pyx_t_1 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2336, __pyx_L1_error)
+      __PYX_ERR(0, 2348, __pyx_L1_error)
     }
     __pyx_t_10 = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":2337
+    /* "pywrapfst.pyx":2349
  *         attach_new_isymbols,
  *         self._fst.get().OutputSymbols() if old_osymbols is None else
  *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
@@ -25996,13 +26166,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
     if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2337, __pyx_L1_error)
+      __PYX_ERR(0, 2349, __pyx_L1_error)
     }
     __pyx_t_10 = __pyx_v_old_osymbols->_table;
   }
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2337, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2349, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2332
+  /* "pywrapfst.pyx":2344
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -26011,7 +26181,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_t_8, __pyx_v_new_isymbols_ptr, __pyx_t_9, __pyx_v_attach_new_isymbols, __pyx_t_10, __pyx_v_new_osymbols_ptr, __pyx_t_11, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2339
+  /* "pywrapfst.pyx":2351
  *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26020,11 +26190,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2339, __pyx_L1_error)
+    __PYX_ERR(0, 2351, __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, 2339, __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, 2351, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2315
+  /* "pywrapfst.pyx":2327
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26043,7 +26213,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2341
+/* "pywrapfst.pyx":2353
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26052,9 +26222,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_40relabel_tables[] = "\n    relabel_tables(self, old_isymbols=None, new_isymbols=None,\n                   unknown_isymbol=\"\", attach_new_isymbols=True,\n                   old_osymbols=None, new_osymbols=None,\n                   unknown_osymbol=\"\", attach_new_osymbols=True)\n\n    Replaces input and/or output labels using SymbolTables.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using user-specified symbol tables; omitted symbols are identity-mapped.\n\n    Args:\n       old_isymbols: The old SymbolTable for input labels, defaulting to the\n          FST's input symbol table.\n       new_isymbols: A SymbolTable used to relabel the input labels\n       unknown_isymbol: Input symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_isymbols be made the FST's input symbol\n          table?\n       old_osymbols: The old SymbolTable for output labels, defaulting to the\n          FST's output symbol table.\n       new_osymbols: A SymbolTable used to relabel the output labels.\n       unknown_osymbol: Outnput symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_osymbols be made the FST's output symbol\n          table?\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No SymbolTable specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_pairs`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_42relabel_tables[] = "\n    relabel_tables(self, old_isymbols=None, new_isymbols=None,\n                   unknown_isymbol=\"\", attach_new_isymbols=True,\n                   old_osymbols=None, new_osymbols=None,\n                   unknown_osymbol=\"\", attach_new_osymbols=True)\n\n    Replaces input and/or output labels using SymbolTables.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using user-specified symbol tables; omitted symbols are identity-mapped.\n\n    Args:\n       old_isymbols: The old SymbolTable for input labels, defaulting to the\n          FST's input symbol table.\n       new_isymbols: A SymbolTable used to relabel the input labels\n       unknown_isymbol: Input symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_isymbols be made the FST's input symbol\n          table?\n       old_osymbols: The old SymbolTable for output labels, defaulting to the\n          FST's output symbol table.\n       new_osymbols: A SymbolTable used to relabel the output labels.\n       unknown_osymbol: Outnput symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_osymbols be made the FST's output symbol\n          table?\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No SymbolTable specified.\n\n    See also: `decode`, `encode`, `project`, `relabel_pairs`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols = 0;
   PyObject *__pyx_v_unknown_isymbol = 0;
@@ -26070,7 +26240,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
     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":2342
+    /* "pywrapfst.pyx":2354
  * 
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26079,7 +26249,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  */
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2343
+    /* "pywrapfst.pyx":2355
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,
  *                      _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26089,7 +26259,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
     values[2] = ((PyObject *)__pyx_kp_b__10);
 
-    /* "pywrapfst.pyx":2346
+    /* "pywrapfst.pyx":2358
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26098,7 +26268,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  */
     values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2347
+    /* "pywrapfst.pyx":2359
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,
  *                      _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26181,7 +26351,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2341, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2353, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26209,10 +26379,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
     __pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)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, 2345, __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, 2357, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2345
+      /* "pywrapfst.pyx":2357
  *                      _SymbolTable new_isymbols=None,
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -26225,10 +26395,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
     __pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)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, 2349, __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, 2361, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2349
+      /* "pywrapfst.pyx":2361
  *                      _SymbolTable new_osymbols=None,
  *                      unknown_osymbol=b"",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
@@ -26240,19 +26410,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
   }
   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, 2341, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2353, __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__SymbolTable, 1, "old_isymbols", 0))) __PYX_ERR(0, 2342, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2343, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2346, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2347, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_40relabel_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);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_isymbols", 0))) __PYX_ERR(0, 2354, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2355, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2358, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2359, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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":2341
+  /* "pywrapfst.pyx":2353
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26269,13 +26439,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2385
+  /* "pywrapfst.pyx":2397
  *     See also: `decode`, `encode`, `project`, `relabel_pairs`.
  *     """
  *     self._relabel_tables(old_isymbols, new_isymbols,             # <<<<<<<<<<<<<<
@@ -26284,10 +26454,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_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, 2385, __pyx_L1_error)
+    __PYX_ERR(0, 2397, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2388
+  /* "pywrapfst.pyx":2400
  *                          unknown_isymbol, attach_new_isymbols,
  *                          old_osymbols, new_osymbols,
  *                          unknown_osymbol, attach_new_osymbols)             # <<<<<<<<<<<<<<
@@ -26303,9 +26473,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_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, 2385, __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, 2397, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2389
+  /* "pywrapfst.pyx":2401
  *                          old_osymbols, new_osymbols,
  *                          unknown_osymbol, attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -26317,7 +26487,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2341
+  /* "pywrapfst.pyx":2353
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26335,7 +26505,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2391
+/* "pywrapfst.pyx":2403
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26351,7 +26521,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2392
+  /* "pywrapfst.pyx":2404
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26360,19 +26530,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(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, 2392, __pyx_L1_error)
+    __PYX_ERR(0, 2404, __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":2393
+    /* "pywrapfst.pyx":2405
  *   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, 2393, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2405, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -26386,14 +26556,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
     }
     __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, 2393, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2405, __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, 2393, __pyx_L1_error)
+    __PYX_ERR(0, 2405, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2392
+    /* "pywrapfst.pyx":2404
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26402,7 +26572,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2394
+  /* "pywrapfst.pyx":2406
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26411,11 +26581,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(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, 2394, __pyx_L1_error)
+    __PYX_ERR(0, 2406, __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, 2394, __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, 2406, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2391
+  /* "pywrapfst.pyx":2403
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26434,7 +26604,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2396
+/* "pywrapfst.pyx":2408
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26443,9 +26613,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_42reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `reserve_states`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `reserve_states`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   size_t __pyx_v_n;
   PyObject *__pyx_r = 0;
@@ -26474,11 +26644,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs(PyObject *__py
         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, 2396, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2408, __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, 2396, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2408, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -26486,30 +26656,30 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs(PyObject *__py
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2396, __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, 2396, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2408, __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, 2408, __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, 2396, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2408, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2414
+  /* "pywrapfst.pyx":2426
  *     See also: `reserve_states`.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -26518,11 +26688,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_arcs");
-    __PYX_ERR(0, 2414, __pyx_L1_error)
+    __PYX_ERR(0, 2426, __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, 2414, __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, 2426, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2415
+  /* "pywrapfst.pyx":2427
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26534,7 +26704,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2396
+  /* "pywrapfst.pyx":2408
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26552,7 +26722,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2417
+/* "pywrapfst.pyx":2429
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26564,7 +26734,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2418
+  /* "pywrapfst.pyx":2430
  * 
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
@@ -26573,11 +26743,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2418, __pyx_L1_error)
+    __PYX_ERR(0, 2430, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2419
+  /* "pywrapfst.pyx":2431
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26586,11 +26756,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2419, __pyx_L1_error)
+    __PYX_ERR(0, 2431, __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, 2419, __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, 2431, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2417
+  /* "pywrapfst.pyx":2429
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26606,7 +26776,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2421
+/* "pywrapfst.pyx":2433
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26615,15 +26785,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_44reserve_states[] = "\n    reserve_states(self, n)\n\n    Reserve n states (best effort).\n\n    Args:\n      n: The number of states to reserve.\n\n    Returns:\n      self.\n\n    See also: `reserve_arcs`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_46reserve_states[] = "\n    reserve_states(self, n)\n\n    Reserve n states (best effort).\n\n    Args:\n      n: The number of states to reserve.\n\n    Returns:\n      self.\n\n    See also: `reserve_arcs`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
   __pyx_t_10basictypes_int64 __pyx_v_n;
   PyObject *__pyx_r = 0;
   __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2421, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2433, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -26631,19 +26801,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_states(PyObject *__
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_n));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_n));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2435
+  /* "pywrapfst.pyx":2447
  *     See also: `reserve_arcs`.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
@@ -26652,11 +26822,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_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, 2435, __pyx_L1_error)
+    __PYX_ERR(0, 2447, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2435, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2447, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2436
+  /* "pywrapfst.pyx":2448
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26668,7 +26838,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2421
+  /* "pywrapfst.pyx":2433
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26686,7 +26856,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2438
+/* "pywrapfst.pyx":2450
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -26713,7 +26883,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2440
+  /* "pywrapfst.pyx":2452
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -26724,11 +26894,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2440, __pyx_L1_error)
+    __PYX_ERR(0, 2452, __pyx_L1_error)
   }
   __pyx_v__potentials.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2441
+  /* "pywrapfst.pyx":2453
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()             # <<<<<<<<<<<<<<
@@ -26737,11 +26907,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2441, __pyx_L1_error)
+    __PYX_ERR(0, 2453, __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":2442
+  /* "pywrapfst.pyx":2454
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -26752,26 +26922,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __pyx_t_2 = __pyx_v_potentials; __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_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2442, __pyx_L1_error)
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2454, __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, 2442, __pyx_L1_error)
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2454, __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, 2442, __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, 2454, __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, 2442, __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, 2454, __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, 2442, __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, 2454, __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, 2442, __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, 2454, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         #endif
       }
@@ -26781,7 +26951,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2442, __pyx_L1_error)
+          else __PYX_ERR(0, 2454, __pyx_L1_error)
         }
         break;
       }
@@ -26790,7 +26960,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __Pyx_XDECREF_SET(__pyx_v_weight, __pyx_t_5);
     __pyx_t_5 = 0;
 
-    /* "pywrapfst.pyx":2443
+    /* "pywrapfst.pyx":2455
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26799,19 +26969,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2443, __pyx_L1_error)
+      __PYX_ERR(0, 2455, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2444
+    /* "pywrapfst.pyx":2456
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
  *                                                             weight))             # <<<<<<<<<<<<<<
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))
  */
-    __pyx_t_6 = __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, 2443, __pyx_L1_error)
+    __pyx_t_6 = __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, 2455, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2443
+    /* "pywrapfst.pyx":2455
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26822,10 +26992,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
       __pyx_v__potentials.get()->push_back(__pyx_t_6);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2443, __pyx_L1_error)
+      __PYX_ERR(0, 2455, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2442
+    /* "pywrapfst.pyx":2454
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -26835,7 +27005,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2445
+  /* "pywrapfst.pyx":2457
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),             # <<<<<<<<<<<<<<
@@ -26844,10 +27014,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2445, __pyx_L1_error)
+    __PYX_ERR(0, 2457, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2446
+  /* "pywrapfst.pyx":2458
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
@@ -26856,7 +27026,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   fst::script::Reweight(__pyx_v_self->_mfst.get(), (*__pyx_v__potentials), fst::script::GetReweightType(__pyx_v_to_final));
 
-  /* "pywrapfst.pyx":2447
+  /* "pywrapfst.pyx":2459
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26865,11 +27035,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2447, __pyx_L1_error)
+    __PYX_ERR(0, 2459, __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, 2447, __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, 2459, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2438
+  /* "pywrapfst.pyx":2450
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -26888,7 +27058,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2449
+/* "pywrapfst.pyx":2461
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26897,9 +27067,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_46reweight[] = "\n    reweight(self, potentials, to_final=False)\n\n    Reweights an FST using an iterable of potentials.\n\n    This operation destructively reweights an FST according to the potentials\n    and in the direction specified by the user. An arc of weight w, with an\n    origin state of potential p and destination state of potential q, is\n    reweighted by p^{-1} \\otimes (w \\otimes q) when reweighting towards the\n    initial state, and by (p \\otimes w) \\otimes q^{-1} when reweighting towards\n    the final states. The weights must be left distributive when reweighting\n    towards the initial state and right distributive when reweighting towards\n    the final states (e.g., TropicalWeight and LogWeight).\n\n    Args:\n      potentials: An iterable of Weight or weight strings.\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_48reweight[] = "\n    reweight(self, potentials, to_final=False)\n\n    Reweights an FST using an iterable of potentials.\n\n    This operation destructively reweights an FST according to the potentials\n    and in the direction specified by the user. An arc of weight w, with an\n    origin state of potential p and destination state of potential q, is\n    reweighted by p^{-1} \\otimes (w \\otimes q) when reweighting towards the\n    initial state, and by (p \\otimes w) \\otimes q^{-1} when reweighting towards\n    the final states. The weights must be left distributive when reweighting\n    towards the initial state and right distributive when reweighting towards\n    the final states (e.g., TropicalWeight and LogWeight).\n\n    Args:\n      potentials: An iterable of Weight or weight strings.\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_potentials = 0;
   bool __pyx_v_to_final;
   PyObject *__pyx_r = 0;
@@ -26932,7 +27102,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reweight(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2449, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2461, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26945,33 +27115,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reweight(PyObject *__pyx_v_
     }
     __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, 2449, __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, 2461, __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, 2449, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2461, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_46reweight(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_potentials, __pyx_v_to_final);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_48reweight(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_potentials, __pyx_v_to_final);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight __pyx_t_1;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2471
+  /* "pywrapfst.pyx":2483
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -26980,13 +27150,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reweight");
-    __PYX_ERR(0, 2471, __pyx_L1_error)
+    __PYX_ERR(0, 2483, __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, 2471, __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, 2483, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2472
+  /* "pywrapfst.pyx":2484
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -26998,7 +27168,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2449
+  /* "pywrapfst.pyx":2461
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -27016,7 +27186,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2474
+/* "pywrapfst.pyx":2486
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27027,7 +27197,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
 static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args) {
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":2476
+  /* "pywrapfst.pyx":2488
  *   cdef void _rmepsilon(self,
  *                        queue_type=b"auto",
  *                        bool connect=True,             # <<<<<<<<<<<<<<
@@ -27036,7 +27206,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   bool __pyx_v_connect = ((bool)1);
 
-  /* "pywrapfst.pyx":2477
+  /* "pywrapfst.pyx":2489
  *                        queue_type=b"auto",
  *                        bool connect=True,
  *                        weight=None,             # <<<<<<<<<<<<<<
@@ -27071,7 +27241,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2480
+  /* "pywrapfst.pyx":2492
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -27080,30 +27250,30 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2480, __pyx_L1_error)
+    __PYX_ERR(0, 2492, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2481
+  /* "pywrapfst.pyx":2493
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.RmEpsilonOptions] opts
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  */
-  __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, 2480, __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, 2492, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2483
+  /* "pywrapfst.pyx":2495
  *                                                        weight)
  *     cdef unique_ptr[fst.RmEpsilonOptions] opts
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
  *                                         connect, wc, nstate, delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2483, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2483, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2495, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2495, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2484
+  /* "pywrapfst.pyx":2496
  *     cdef unique_ptr[fst.RmEpsilonOptions] opts
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  *                                         connect, wc, nstate, delta))             # <<<<<<<<<<<<<<
@@ -27112,7 +27282,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   __pyx_v_opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_connect, __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta));
 
-  /* "pywrapfst.pyx":2485
+  /* "pywrapfst.pyx":2497
  *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  *                                         connect, wc, nstate, delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -27121,11 +27291,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(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, 2485, __pyx_L1_error)
+    __PYX_ERR(0, 2497, __pyx_L1_error)
   }
   fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":2486
+  /* "pywrapfst.pyx":2498
  *                                         connect, wc, nstate, delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27134,11 +27304,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2486, __pyx_L1_error)
+    __PYX_ERR(0, 2498, __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, 2486, __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, 2498, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2474
+  /* "pywrapfst.pyx":2486
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27154,7 +27324,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2488
+/* "pywrapfst.pyx":2500
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27163,9 +27333,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_48rmepsilon[] = "\n    rmepsilon(self, queue_type=\"auto\", connect=True, weight=None,\n              nstate=NO_STATE_ID, delta=1e-6):\n\n    Removes epsilon transitions.\n\n    This operation destructively removes epsilon transitions, i.e., those where\n    both input and output labels are epsilon) from an FST.\n\n    Args:\n      queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n          \"lifo\", \"shortest\", \"state\", \"top\".\n      connect: Should output be trimmed?\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n      nstate: State number threshold.\n      delta: Comparison/quantization delta.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_50rmepsilon[] = "\n    rmepsilon(self, queue_type=\"auto\", connect=True, weight=None,\n              nstate=NO_STATE_ID, delta=1e-6):\n\n    Removes epsilon transitions.\n\n    This operation destructively removes epsilon transitions, i.e., those where\n    both input and output labels are epsilon) from an FST.\n\n    Args:\n      queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n          \"lifo\", \"shortest\", \"state\", \"top\".\n      connect: Should output be trimmed?\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n      nstate: State number threshold.\n      delta: Comparison/quantization delta.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_connect;
   PyObject *__pyx_v_weight = 0;
@@ -27179,7 +27349,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
     PyObject* values[5] = {0,0,0,0,0};
     values[0] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":2491
+    /* "pywrapfst.pyx":2503
  *                 queue_type=b"auto",
  *                 bool connect=True,
  *                 weight=None,             # <<<<<<<<<<<<<<
@@ -27237,7 +27407,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(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, 2488, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2500, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27257,10 +27427,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(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, 2490, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2502, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2490
+      /* "pywrapfst.pyx":2502
  *   def rmepsilon(self,
  *                 queue_type=b"auto",
  *                 bool connect=True,             # <<<<<<<<<<<<<<
@@ -27271,27 +27441,27 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2492, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2504, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__21;
     }
     if (values[4]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2493, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2505, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__22;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2488, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2500, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_queue_type, __pyx_v_connect, __pyx_v_weight, __pyx_v_nstate, __pyx_v_delta);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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":2488
+  /* "pywrapfst.pyx":2500
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27304,13 +27474,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon __pyx_t_1;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2515
+  /* "pywrapfst.pyx":2527
  *       self.
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -27319,7 +27489,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_rmepsilon");
-    __PYX_ERR(0, 2515, __pyx_L1_error)
+    __PYX_ERR(0, 2527, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 5;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
@@ -27327,9 +27497,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   __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, 2515, __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, 2527, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2516
+  /* "pywrapfst.pyx":2528
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -27341,7 +27511,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2488
+  /* "pywrapfst.pyx":2500
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27359,7 +27529,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2518
+/* "pywrapfst.pyx":2530
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27383,7 +27553,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2519
+  /* "pywrapfst.pyx":2531
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27392,19 +27562,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(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, 2519, __pyx_L1_error)
+    __PYX_ERR(0, 2531, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2520
+    /* "pywrapfst.pyx":2532
  *   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 wc = _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, 2520, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2532, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27418,14 +27588,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __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, 2520, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2532, __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, 2520, __pyx_L1_error)
+    __PYX_ERR(0, 2532, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2519
+    /* "pywrapfst.pyx":2531
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27434,7 +27604,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2521
+  /* "pywrapfst.pyx":2533
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -27443,20 +27613,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2521, __pyx_L1_error)
+    __PYX_ERR(0, 2533, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2522
+  /* "pywrapfst.pyx":2534
  *       raise FstIndexError("State index out of range")
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().SetFinal(state, wc):
  *       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, 2521, __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, 2533, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_5;
 
-  /* "pywrapfst.pyx":2523
+  /* "pywrapfst.pyx":2535
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27465,19 +27635,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(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, 2523, __pyx_L1_error)
+    __PYX_ERR(0, 2535, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v_wc) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2524
+    /* "pywrapfst.pyx":2536
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):
  *       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, 2524, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2536, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27491,14 +27661,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __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, 2524, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2536, __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, 2524, __pyx_L1_error)
+    __PYX_ERR(0, 2536, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2523
+    /* "pywrapfst.pyx":2535
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27507,7 +27677,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2525
+  /* "pywrapfst.pyx":2537
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27516,11 +27686,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2525, __pyx_L1_error)
+    __PYX_ERR(0, 2537, __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, 2525, __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, 2537, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2518
+  /* "pywrapfst.pyx":2530
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27539,7 +27709,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2527
+/* "pywrapfst.pyx":2539
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27548,9 +27718,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_50set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n\n    See also: `set_start`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_52set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n\n    See also: `set_start`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_v_weight = 0;
   PyObject *__pyx_r = 0;
@@ -27584,7 +27754,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51set_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, 2527, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2539, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27595,31 +27765,31 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51set_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2527, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2539, __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, 2527, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2539, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_50set_final(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_weight);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_52set_final(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_weight);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final __pyx_t_1;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2547
+  /* "pywrapfst.pyx":2559
  *     See also: `set_start`.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
@@ -27628,13 +27798,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_final");
-    __PYX_ERR(0, 2547, __pyx_L1_error)
+    __PYX_ERR(0, 2559, __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, 2547, __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, 2559, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2548
+  /* "pywrapfst.pyx":2560
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -27646,7 +27816,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2527
+  /* "pywrapfst.pyx":2539
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27664,7 +27834,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2550
+/* "pywrapfst.pyx":2562
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27678,7 +27848,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2551
+  /* "pywrapfst.pyx":2563
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27689,7 +27859,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2552
+    /* "pywrapfst.pyx":2564
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -27698,11 +27868,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2552, __pyx_L1_error)
+      __PYX_ERR(0, 2564, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2553
+    /* "pywrapfst.pyx":2565
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -27711,7 +27881,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2551
+    /* "pywrapfst.pyx":2563
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27720,7 +27890,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   }
 
-  /* "pywrapfst.pyx":2554
+  /* "pywrapfst.pyx":2566
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
  *     self._mfst.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -27729,15 +27899,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2554, __pyx_L1_error)
+    __PYX_ERR(0, 2566, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2554, __pyx_L1_error)
+    __PYX_ERR(0, 2566, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2555
+  /* "pywrapfst.pyx":2567
  *       return
  *     self._mfst.get().SetInputSymbols(syms._table)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27746,11 +27916,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2555, __pyx_L1_error)
+    __PYX_ERR(0, 2567, __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, 2555, __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, 2567, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2550
+  /* "pywrapfst.pyx":2562
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27766,7 +27936,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2557
+/* "pywrapfst.pyx":2569
  *     self._check_mutating_imethod()
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -27775,14 +27945,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_52set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_output_symbols`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_54set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_output_symbols`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2557, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_52set_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2569, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
   goto __pyx_L0;
@@ -27793,12 +27963,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_input_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2573
+  /* "pywrapfst.pyx":2585
  *     See also: `set_output_symbols`.
  *     """
  *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
@@ -27807,11 +27977,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_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, 2573, __pyx_L1_error)
+    __PYX_ERR(0, 2585, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2573, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2585, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2574
+  /* "pywrapfst.pyx":2586
  *     """
  *     self._set_input_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -27823,7 +27993,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_input_symbols(struct __
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2557
+  /* "pywrapfst.pyx":2569
  *     self._check_mutating_imethod()
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -27841,7 +28011,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_input_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2576
+/* "pywrapfst.pyx":2588
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27855,7 +28025,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2577
+  /* "pywrapfst.pyx":2589
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27866,7 +28036,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2578
+    /* "pywrapfst.pyx":2590
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
@@ -27875,11 +28045,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2578, __pyx_L1_error)
+      __PYX_ERR(0, 2590, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2579
+    /* "pywrapfst.pyx":2591
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
@@ -27888,7 +28058,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2577
+    /* "pywrapfst.pyx":2589
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -27897,7 +28067,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":2580
+  /* "pywrapfst.pyx":2592
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
  *     self._mfst.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -27906,15 +28076,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2580, __pyx_L1_error)
+    __PYX_ERR(0, 2592, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2580, __pyx_L1_error)
+    __PYX_ERR(0, 2592, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2581
+  /* "pywrapfst.pyx":2593
  *       return
  *     self._mfst.get().SetOutputSymbols(syms._table)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27923,11 +28093,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2581, __pyx_L1_error)
+    __PYX_ERR(0, 2593, __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, 2581, __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, 2593, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2576
+  /* "pywrapfst.pyx":2588
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -27943,7 +28113,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2583
+/* "pywrapfst.pyx":2595
  *     self._check_mutating_imethod()
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -27952,14 +28122,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_54set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_input_symbols`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_56set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n\n    See also: `set_input_symbols`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2583, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_54set_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2595, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
   goto __pyx_L0;
@@ -27970,12 +28140,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_output_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2599
+  /* "pywrapfst.pyx":2611
  *     See also: `set_input_symbols`.
  *     """
  *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
@@ -27984,11 +28154,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_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, 2599, __pyx_L1_error)
+    __PYX_ERR(0, 2611, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2599, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2611, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2600
+  /* "pywrapfst.pyx":2612
  *     """
  *     self._set_output_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -28000,7 +28170,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_output_symbols(struct _
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2583
+  /* "pywrapfst.pyx":2595
  *     self._check_mutating_imethod()
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -28018,7 +28188,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_output_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2602
+/* "pywrapfst.pyx":2614
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28030,7 +28200,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_set_properties", 0);
 
-  /* "pywrapfst.pyx":2603
+  /* "pywrapfst.pyx":2615
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):
  *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
@@ -28039,11 +28209,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2603, __pyx_L1_error)
+    __PYX_ERR(0, 2615, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2602
+  /* "pywrapfst.pyx":2614
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28059,7 +28229,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2605
+/* "pywrapfst.pyx":2617
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28068,9 +28238,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_56set_properties[] = "\n    set_properties(self, props, mask)\n\n    Sets the properties bits.\n\n    Args:\n      props: The properties to be set.\n      mask: A mask to be applied to the `props` argument before setting the\n          FST's properties.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_58set_properties[] = "\n    set_properties(self, props, mask)\n\n    Sets the properties bits.\n\n    Args:\n      props: The properties to be set.\n      mask: A mask to be applied to the `props` argument before setting the\n          FST's properties.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_uint64 __pyx_v_props;
   __pyx_t_10basictypes_uint64 __pyx_v_mask;
   PyObject *__pyx_r = 0;
@@ -28099,11 +28269,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_properties(PyObject *__
         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, 2605, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2617, __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, 2605, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2617, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -28111,30 +28281,30 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_properties(PyObject *__
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2605, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2605, __pyx_L3_error)
+    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2617, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2617, __pyx_L3_error)
   }
   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, 2605, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2617, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_56set_properties(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_props, __pyx_v_mask);
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_58set_properties(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_props, __pyx_v_mask);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2619
+  /* "pywrapfst.pyx":2631
  *       self.
  *     """
  *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
@@ -28143,11 +28313,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_properties(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_properties");
-    __PYX_ERR(0, 2619, __pyx_L1_error)
+    __PYX_ERR(0, 2631, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_properties(__pyx_v_self, __pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2620
+  /* "pywrapfst.pyx":2632
  *     """
  *     self._set_properties(props, mask)
  *     return self             # <<<<<<<<<<<<<<
@@ -28159,7 +28329,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_properties(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2605
+  /* "pywrapfst.pyx":2617
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -28177,7 +28347,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_properties(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2622
+/* "pywrapfst.pyx":2634
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -28193,7 +28363,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2623
+  /* "pywrapfst.pyx":2635
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -28202,19 +28372,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(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, 2623, __pyx_L1_error)
+    __PYX_ERR(0, 2635, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2624
+    /* "pywrapfst.pyx":2636
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):
  *       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, 2624, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2636, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28228,14 +28398,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
     }
     __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, 2624, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2636, __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, 2624, __pyx_L1_error)
+    __PYX_ERR(0, 2636, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2623
+    /* "pywrapfst.pyx":2635
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -28244,7 +28414,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2625
+  /* "pywrapfst.pyx":2637
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28253,11 +28423,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2625, __pyx_L1_error)
+    __PYX_ERR(0, 2637, __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, 2625, __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, 2637, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2622
+  /* "pywrapfst.pyx":2634
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -28276,7 +28446,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2627
+/* "pywrapfst.pyx":2639
  *     self._check_mutating_imethod()
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -28285,15 +28455,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_58set_start[] = "\n    set_start(self, state)\n\n    Sets a state to be the initial state state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `set_final`.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_60set_start[] = "\n    set_start(self, state)\n\n    Sets a state to be the initial state state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n\n    See also: `set_final`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2627, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2639, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -28301,19 +28471,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_start(PyObject *__pyx_v
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_58set_start(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_60set_start(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2644
+  /* "pywrapfst.pyx":2656
  *     See also: `set_final`.
  *     """
  *     self._set_start(state)             # <<<<<<<<<<<<<<
@@ -28322,11 +28492,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_start(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_start");
-    __PYX_ERR(0, 2644, __pyx_L1_error)
+    __PYX_ERR(0, 2656, __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, 2644, __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, 2656, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2645
+  /* "pywrapfst.pyx":2657
  *     """
  *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
@@ -28338,7 +28508,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_start(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2627
+  /* "pywrapfst.pyx":2639
  *     self._check_mutating_imethod()
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -28356,7 +28526,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_start(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2647
+/* "pywrapfst.pyx":2659
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28372,7 +28542,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2649
+  /* "pywrapfst.pyx":2661
  *   cdef void _topsort(self) except *:
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -28381,21 +28551,21 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(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, 2649, __pyx_L1_error)
+    __PYX_ERR(0, 2661, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2650
+    /* "pywrapfst.pyx":2662
  *     # 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")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2650, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2662, __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, 2650, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2662, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -28410,12 +28580,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
     }
     __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, 2650, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2662, __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":2649
+    /* "pywrapfst.pyx":2661
  *   cdef void _topsort(self) except *:
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -28424,7 +28594,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":2651
+  /* "pywrapfst.pyx":2663
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28433,11 +28603,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(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, 2651, __pyx_L1_error)
+    __PYX_ERR(0, 2663, __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, 2651, __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, 2663, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2647
+  /* "pywrapfst.pyx":2659
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28456,7 +28626,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2653
+/* "pywrapfst.pyx":2665
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28465,25 +28635,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_60topsort[] = "\n    topsort(self)\n\n    Sorts transitions by state IDs.\n\n    This operation destructively topologically sorts the FST, if it is acyclic;\n    otherwise it remains unchanged. Once sorted, all transitions are from lower\n    state IDs to higher state IDs\n\n    Returns:\n       self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_62topsort[] = "\n    topsort(self)\n\n    Sorts transitions by state IDs.\n\n    This operation destructively topologically sorts the FST, if it is acyclic;\n    otherwise it remains unchanged. Once sorted, all transitions are from lower\n    state IDs to higher state IDs\n\n    Returns:\n       self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_60topsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_62topsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2666
+  /* "pywrapfst.pyx":2678
  *        self.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -28492,11 +28662,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_topsort");
-    __PYX_ERR(0, 2666, __pyx_L1_error)
+    __PYX_ERR(0, 2678, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2666, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2678, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2667
+  /* "pywrapfst.pyx":2679
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
@@ -28508,7 +28678,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2653
+  /* "pywrapfst.pyx":2665
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28526,7 +28696,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2669
+/* "pywrapfst.pyx":2681
  *     return self
  * 
  *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -28538,7 +28708,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_union", 0);
 
-  /* "pywrapfst.pyx":2670
+  /* "pywrapfst.pyx":2682
  * 
  *   cdef void _union(self, _Fst ifst) except *:
  *     fst.Union(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
@@ -28547,15 +28717,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(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, 2670, __pyx_L1_error)
+    __PYX_ERR(0, 2682, __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, 2670, __pyx_L1_error)
+    __PYX_ERR(0, 2682, __pyx_L1_error)
   }
   fst::script::Union(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
 
-  /* "pywrapfst.pyx":2671
+  /* "pywrapfst.pyx":2683
  *   cdef void _union(self, _Fst ifst) except *:
  *     fst.Union(self._mfst.get(), deref(ifst._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28564,11 +28734,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(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, 2671, __pyx_L1_error)
+    __PYX_ERR(0, 2683, __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, 2671, __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, 2683, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2669
+  /* "pywrapfst.pyx":2681
  *     return self
  * 
  *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -28584,7 +28754,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2673
+/* "pywrapfst.pyx":2685
  *     self._check_mutating_imethod()
  * 
  *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -28593,14 +28763,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_62union[] = "\n    union(self, ifst)\n\n    Computes the union (sum) of two FSTs.\n\n    This operation computes the union (sum) of two FSTs. If A transduces string\n    x to y with weight a and B transduces string w to v with weight b, then\n    their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst); /*proto*/
+static char __pyx_doc_9pywrapfst_11_MutableFst_64union[] = "\n    union(self, ifst)\n\n    Computes the union (sum) of two FSTs.\n\n    This operation computes the union (sum) of two FSTs. If A transduces string\n    x to y with weight a and B transduces string w to v with weight b, then\n    their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      ifst: The second input FST.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_v_ifst) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("union (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 2673, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_62union(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 2685, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_64union(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
 
   /* function exit code */
   goto __pyx_L0;
@@ -28611,12 +28781,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63union(PyObject *__pyx_v_sel
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2689
+  /* "pywrapfst.pyx":2701
  *       self.
  *     """
  *     self._union(ifst)             # <<<<<<<<<<<<<<
@@ -28625,11 +28795,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_union");
-    __PYX_ERR(0, 2689, __pyx_L1_error)
+    __PYX_ERR(0, 2701, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_union(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2689, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_union(__pyx_v_self, __pyx_v_ifst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2701, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2690
+  /* "pywrapfst.pyx":2702
  *     """
  *     self._union(ifst)
  *     return self             # <<<<<<<<<<<<<<
@@ -28641,7 +28811,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2673
+  /* "pywrapfst.pyx":2685
  *     self._check_mutating_imethod()
  * 
  *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -28659,7 +28829,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2715
+/* "pywrapfst.pyx":2727
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28677,7 +28847,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2716
+  /* "pywrapfst.pyx":2728
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28687,14 +28857,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2717
+    /* "pywrapfst.pyx":2729
  * 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, 2717, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2729, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28708,14 +28878,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
     }
     __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, 2717, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2729, __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, 2717, __pyx_L1_error)
+    __PYX_ERR(0, 2729, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2716
+    /* "pywrapfst.pyx":2728
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28724,19 +28894,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
  */
   }
 
-  /* "pywrapfst.pyx":2718
+  /* "pywrapfst.pyx":2730
  *   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, 2718, __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, 2730, __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":2719
+  /* "pywrapfst.pyx":2731
  *     raise FstOpError("Operation failed")
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -28745,11 +28915,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2719, __pyx_L1_error)
+    __PYX_ERR(0, 2731, __pyx_L1_error)
   }
   __pyx_v_ofst->_fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2720
+  /* "pywrapfst.pyx":2732
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(tfst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -28761,7 +28931,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2715
+  /* "pywrapfst.pyx":2727
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28783,7 +28953,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2723
+/* "pywrapfst.pyx":2735
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28801,7 +28971,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2724
+  /* "pywrapfst.pyx":2736
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28811,14 +28981,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2725
+    /* "pywrapfst.pyx":2737
  * 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, 2725, __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))) {
@@ -28832,14 +29002,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
     }
     __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, 2725, __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, 2725, __pyx_L1_error)
+    __PYX_ERR(0, 2737, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2724
+    /* "pywrapfst.pyx":2736
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -28848,19 +29018,19 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   }
 
-  /* "pywrapfst.pyx":2726
+  /* "pywrapfst.pyx":2738
  *   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, 2726, __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, 2738, __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":2727
+  /* "pywrapfst.pyx":2739
  *     raise FstOpError("Operation failed")
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
@@ -28869,11 +29039,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2727, __pyx_L1_error)
+    __PYX_ERR(0, 2739, __pyx_L1_error)
   }
   __pyx_v_ofst->__pyx_base._fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2729
+  /* "pywrapfst.pyx":2741
  *   ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)             # <<<<<<<<<<<<<<
@@ -28882,15 +29052,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2729, __pyx_L1_error)
+    __PYX_ERR(0, 2741, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2729, __pyx_L1_error)
+    __PYX_ERR(0, 2741, __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":2730
+  /* "pywrapfst.pyx":2742
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -28902,7 +29072,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2723
+  /* "pywrapfst.pyx":2735
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28924,7 +29094,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2733
+/* "pywrapfst.pyx":2745
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28939,7 +29109,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("_init_XFst", 0);
 
-  /* "pywrapfst.pyx":2734
+  /* "pywrapfst.pyx":2746
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -28949,7 +29119,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kMutable, 1) == fst::kMutable) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2735
+    /* "pywrapfst.pyx":2747
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
@@ -28957,13 +29127,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  *     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, 2735, __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, 2747, __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":2734
+    /* "pywrapfst.pyx":2746
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -28972,7 +29142,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  */
   }
 
-  /* "pywrapfst.pyx":2737
+  /* "pywrapfst.pyx":2749
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -28981,14 +29151,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  */
   /*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, 2737, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2749, __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":2733
+  /* "pywrapfst.pyx":2745
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -29007,7 +29177,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2740
+/* "pywrapfst.pyx":2752
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29034,17 +29204,17 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     }
   }
 
-  /* "pywrapfst.pyx":2742
+  /* "pywrapfst.pyx":2754
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2742, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2754, __pyx_L1_error)
   __pyx_v_tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2743
+  /* "pywrapfst.pyx":2755
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29054,16 +29224,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2744
+    /* "pywrapfst.pyx":2756
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2744, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2756, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2744, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2756, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -29077,7 +29247,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2744, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2756, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -29093,14 +29263,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2744, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2756, __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, 2744, __pyx_L1_error)
+    __PYX_ERR(0, 2756, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2743
+    /* "pywrapfst.pyx":2755
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29109,7 +29279,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  */
   }
 
-  /* "pywrapfst.pyx":2745
+  /* "pywrapfst.pyx":2757
  *   if tfst.get() == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -29117,13 +29287,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  * 
  */
   __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, 2745, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2757, __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":2740
+  /* "pywrapfst.pyx":2752
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29146,7 +29316,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2748
+/* "pywrapfst.pyx":2760
  * 
  * 
  * cpdef _Fst _read(filename):             # <<<<<<<<<<<<<<
@@ -29168,17 +29338,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_read", 0);
 
-  /* "pywrapfst.pyx":2750
+  /* "pywrapfst.pyx":2762
  * cpdef _Fst _read(filename):
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(filename)))             # <<<<<<<<<<<<<<
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2750, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2762, __pyx_L1_error)
   __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2751
+  /* "pywrapfst.pyx":2763
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(filename)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29188,16 +29358,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2752
+    /* "pywrapfst.pyx":2764
  *   tfst.reset(fst.FstClass.Read(tostring(filename)))
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2752, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2764, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2752, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2764, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -29211,7 +29381,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2752, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2764, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -29227,14 +29397,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2752, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2764, __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, 2752, __pyx_L1_error)
+    __PYX_ERR(0, 2764, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2751
+    /* "pywrapfst.pyx":2763
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(filename)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29243,7 +29413,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
  */
   }
 
-  /* "pywrapfst.pyx":2753
+  /* "pywrapfst.pyx":2765
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed: {!r}".format(filename))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -29251,13 +29421,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
  * 
  */
   __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, 2753, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2765, __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":2748
+  /* "pywrapfst.pyx":2760
  * 
  * 
  * cpdef _Fst _read(filename):             # <<<<<<<<<<<<<<
@@ -29299,7 +29469,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_read", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2748, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2760, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -29316,7 +29486,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2756
+/* "pywrapfst.pyx":2768
  * 
  * 
  * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
@@ -29337,17 +29507,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
 
-  /* "pywrapfst.pyx":2758
+  /* "pywrapfst.pyx":2770
  * cpdef _Fst _read_Fst_from_string(state):
  *   cdef stringstream sstrm
  *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2758, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2770, __pyx_L1_error)
   (void)((__pyx_v_sstrm << __pyx_t_1));
 
-  /* "pywrapfst.pyx":2760
+  /* "pywrapfst.pyx":2772
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -29356,7 +29526,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":2761
+  /* "pywrapfst.pyx":2773
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29366,14 +29536,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2762
+    /* "pywrapfst.pyx":2774
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2762, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2774, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -29387,14 +29557,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2762, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2774, __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, 2762, __pyx_L1_error)
+    __PYX_ERR(0, 2774, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2761
+    /* "pywrapfst.pyx":2773
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -29403,7 +29573,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   }
 
-  /* "pywrapfst.pyx":2763
+  /* "pywrapfst.pyx":2775
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -29411,13 +29581,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  * 
  */
   __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, 2763, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2775, __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":2756
+  /* "pywrapfst.pyx":2768
  * 
  * 
  * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
@@ -29457,7 +29627,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObj
   PyObject *__pyx_t_1 = NULL;
   __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, 2756, __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, 2768, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -29474,7 +29644,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst_from_string(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2783
+/* "pywrapfst.pyx":2795
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29519,7 +29689,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_1__new__(PyObject *__pyx_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) __PYX_ERR(0, 2783, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) __PYX_ERR(0, 2795, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29535,7 +29705,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_1__new__(PyObject *__pyx_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2783, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2795, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29555,7 +29725,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_
   struct __pyx_opt_args_9pywrapfst__create_Fst __pyx_t_2;
   __Pyx_RefNannySetupContext("__new__", 0);
 
-  /* "pywrapfst.pyx":2784
+  /* "pywrapfst.pyx":2796
  * 
  *    def __new__(cls, arc_type=b"standard"):
  *     return _create_Fst(arc_type)             # <<<<<<<<<<<<<<
@@ -29565,13 +29735,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.arc_type = __pyx_v_arc_type;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__create_Fst(&__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2784, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__create_Fst(&__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2796, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2783
+  /* "pywrapfst.pyx":2795
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29590,7 +29760,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2787
+/* "pywrapfst.pyx":2799
  * 
  *    @staticmethod
  *    def read(filename):             # <<<<<<<<<<<<<<
@@ -29619,7 +29789,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":2802
+  /* "pywrapfst.pyx":2814
  *        FstIOError: Read failed.
  *      """
  *      return _read(filename)             # <<<<<<<<<<<<<<
@@ -29627,13 +29797,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
  *    @staticmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2802, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_filename, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2814, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2787
+  /* "pywrapfst.pyx":2799
  * 
  *    @staticmethod
  *    def read(filename):             # <<<<<<<<<<<<<<
@@ -29652,7 +29822,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2805
+/* "pywrapfst.pyx":2817
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -29681,7 +29851,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":2823
+  /* "pywrapfst.pyx":2835
  *      See also: `write_to_string`.
  *      """
  *      return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
@@ -29689,13 +29859,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
  * 
  */
   __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, 2823, __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, 2835, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2805
+  /* "pywrapfst.pyx":2817
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -29714,7 +29884,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2936
+/* "pywrapfst.pyx":2948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29744,7 +29914,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":2937
+  /* "pywrapfst.pyx":2949
  * 
  *   def __repr__(self):
  *     return "<Arc at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -29752,9 +29922,9 @@ 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_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2937, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2937, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -29769,14 +29939,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2937, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2949, __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":2936
+  /* "pywrapfst.pyx":2948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29798,7 +29968,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2939
+/* "pywrapfst.pyx":2951
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -29843,23 +30013,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, 2939, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 2951, __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, 2939, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 2951, __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, 2939, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 2951, __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, 2939, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2951, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -29869,14 +30039,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2939, __pyx_L3_error)
-    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2939, __pyx_L3_error)
+    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2951, __pyx_L3_error)
+    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2951, __pyx_L3_error)
     __pyx_v_weight = values[2];
-    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2939, __pyx_L3_error)
+    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2951, __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, 2939, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2951, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29896,17 +30066,17 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2940
+  /* "pywrapfst.pyx":2952
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2940, __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, 2952, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2941
+  /* "pywrapfst.pyx":2953
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))             # <<<<<<<<<<<<<<
@@ -29915,11 +30085,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, 2941, __pyx_L1_error)
+    __PYX_ERR(0, 2953, __pyx_L1_error)
   }
   __pyx_v_self->_arc.reset(new fst::script::ArcClass(__pyx_v_ilabel, __pyx_v_olabel, __pyx_v_wc, __pyx_v_nextstate));
 
-  /* "pywrapfst.pyx":2939
+  /* "pywrapfst.pyx":2951
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -29938,7 +30108,7 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2943
+/* "pywrapfst.pyx":2955
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -29965,7 +30135,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, 2943, __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, 2955, __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));
@@ -29982,10 +30152,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, 2943, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2955, __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, 2943, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 2955, __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;
@@ -30004,7 +30174,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":2944
+  /* "pywrapfst.pyx":2956
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -30012,15 +30182,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, 2944, __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, 2956, __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, 2944, __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, 2956, __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, 2944, __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, 2956, __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, 2944, __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, 2956, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2944, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2956, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -30034,14 +30204,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, 2944, __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, 2956, __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":2943
+  /* "pywrapfst.pyx":2955
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -30083,7 +30253,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   PyObject *__pyx_t_1 = NULL;
   __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, 2943, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2955, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30100,7 +30270,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2948
+/* "pywrapfst.pyx":2960
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30127,7 +30297,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2949
+  /* "pywrapfst.pyx":2961
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -30137,15 +30307,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, 2949, __pyx_L1_error)
+    __PYX_ERR(0, 2961, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2949, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2961, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2948
+  /* "pywrapfst.pyx":2960
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30164,7 +30334,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2951
+/* "pywrapfst.pyx":2963
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30180,7 +30350,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2951, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2963, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30200,7 +30370,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2952
+  /* "pywrapfst.pyx":2964
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -30209,11 +30379,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, 2952, __pyx_L1_error)
+    __PYX_ERR(0, 2964, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2951
+  /* "pywrapfst.pyx":2963
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30232,7 +30402,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2956
+/* "pywrapfst.pyx":2968
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30259,7 +30429,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2957
+  /* "pywrapfst.pyx":2969
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -30269,15 +30439,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, 2957, __pyx_L1_error)
+    __PYX_ERR(0, 2969, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2957, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2969, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2956
+  /* "pywrapfst.pyx":2968
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30296,7 +30466,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2959
+/* "pywrapfst.pyx":2971
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30312,7 +30482,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2959, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2971, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30332,7 +30502,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2960
+  /* "pywrapfst.pyx":2972
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -30341,11 +30511,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, 2960, __pyx_L1_error)
+    __PYX_ERR(0, 2972, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2959
+  /* "pywrapfst.pyx":2971
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30364,7 +30534,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2964
+/* "pywrapfst.pyx":2976
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30392,19 +30562,19 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2965
+  /* "pywrapfst.pyx":2977
  * 
  *     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, 2965, __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, 2977, __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":2966
+  /* "pywrapfst.pyx":2978
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
@@ -30413,15 +30583,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, 2966, __pyx_L1_error)
+    __PYX_ERR(0, 2978, __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, 2966, __pyx_L1_error)
+    __PYX_ERR(0, 2978, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":2967
+  /* "pywrapfst.pyx":2979
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight             # <<<<<<<<<<<<<<
@@ -30433,7 +30603,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2964
+  /* "pywrapfst.pyx":2976
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30453,7 +30623,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2969
+/* "pywrapfst.pyx":2981
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30480,21 +30650,21 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2970
+  /* "pywrapfst.pyx":2982
  * 
  *     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, 2970, __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, 2982, __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, 2970, __pyx_L1_error)
+    __PYX_ERR(0, 2982, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2969
+  /* "pywrapfst.pyx":2981
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30513,7 +30683,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2974
+/* "pywrapfst.pyx":2986
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30540,7 +30710,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2975
+  /* "pywrapfst.pyx":2987
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -30550,15 +30720,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, 2975, __pyx_L1_error)
+    __PYX_ERR(0, 2987, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2987, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2974
+  /* "pywrapfst.pyx":2986
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30577,7 +30747,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2977
+/* "pywrapfst.pyx":2989
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30593,7 +30763,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2977, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2989, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30613,7 +30783,7 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2978
+  /* "pywrapfst.pyx":2990
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -30622,11 +30792,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, 2978, __pyx_L1_error)
+    __PYX_ERR(0, 2990, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":2989
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30752,7 +30922,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2981
+/* "pywrapfst.pyx":2993
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -30770,19 +30940,19 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Arc", 0);
 
-  /* "pywrapfst.pyx":2982
+  /* "pywrapfst.pyx":2994
  * 
  * 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, 2982, __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, 2994, __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":2983
+  /* "pywrapfst.pyx":2995
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
@@ -30791,11 +30961,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, 2983, __pyx_L1_error)
+    __PYX_ERR(0, 2995, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":2984
+  /* "pywrapfst.pyx":2996
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)             # <<<<<<<<<<<<<<
@@ -30803,13 +30973,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, 2984, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2996, __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, 2984, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __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, 2984, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2996, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2984, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2996, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
@@ -30823,14 +30993,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, 2984, __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, 2996, __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":2981
+  /* "pywrapfst.pyx":2993
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -30853,7 +31023,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2995
+/* "pywrapfst.pyx":3007
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -30883,7 +31053,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":2996
+  /* "pywrapfst.pyx":3008
  * 
  *   def __repr__(self):
  *     return "<ArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -30891,9 +31061,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
  *   def __init__(self, _Fst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3008, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3008, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -30908,14 +31078,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3008, __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":2995
+  /* "pywrapfst.pyx":3007
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -30937,7 +31107,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2998
+/* "pywrapfst.pyx":3010
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -30976,11 +31146,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, 2998, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3010, __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, 2998, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3010, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -30989,17 +31159,17 @@ 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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2998, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3010, __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, 2998, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3010, __pyx_L3_error)
   __pyx_L3_error:;
   __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, 2998, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3010, __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);
 
   /* function exit code */
@@ -31021,7 +31191,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   std::shared_ptr<fst::script::FstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2999
+  /* "pywrapfst.pyx":3011
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31030,19 +31200,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, 2999, __pyx_L1_error)
+    __PYX_ERR(0, 3011, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3000
+    /* "pywrapfst.pyx":3012
  *   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, 3000, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3012, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -31056,14 +31226,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, 3000, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3012, __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, 3000, __pyx_L1_error)
+    __PYX_ERR(0, 3012, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2999
+    /* "pywrapfst.pyx":3011
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31072,7 +31242,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":3002
+  /* "pywrapfst.pyx":3014
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -31081,16 +31251,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, 3002, __pyx_L1_error)
+    __PYX_ERR(0, 3014, __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, 3002, __pyx_L1_error)
+    __PYX_ERR(0, 3014, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3003
+  /* "pywrapfst.pyx":3015
  *     # 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))             # <<<<<<<<<<<<<<
@@ -31099,15 +31269,15 @@ 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, 3003, __pyx_L1_error)
+    __PYX_ERR(0, 3015, __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, 3003, __pyx_L1_error)
+    __PYX_ERR(0, 3015, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":2998
+  /* "pywrapfst.pyx":3010
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -31129,7 +31299,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3006
+/* "pywrapfst.pyx":3018
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31155,7 +31325,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3007
+  /* "pywrapfst.pyx":3019
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -31167,7 +31337,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3006
+  /* "pywrapfst.pyx":3018
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31182,7 +31352,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3010
+/* "pywrapfst.pyx":3022
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31211,7 +31381,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3011
+  /* "pywrapfst.pyx":3023
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31220,12 +31390,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, 3011, __pyx_L1_error)
+    __PYX_ERR(0, 3023, __pyx_L1_error)
   }
   __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":3012
+    /* "pywrapfst.pyx":3024
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -31233,9 +31403,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, 3012, __pyx_L1_error)
+    __PYX_ERR(0, 3024, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3011
+    /* "pywrapfst.pyx":3023
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31244,7 +31414,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":3013
+  /* "pywrapfst.pyx":3025
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -31253,14 +31423,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, 3013, __pyx_L1_error)
+    __PYX_ERR(0, 3025, __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, 3013, __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, 3025, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3014
+  /* "pywrapfst.pyx":3026
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -31269,11 +31439,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, 3014, __pyx_L1_error)
+    __PYX_ERR(0, 3026, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3015
+  /* "pywrapfst.pyx":3027
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -31285,7 +31455,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3010
+  /* "pywrapfst.pyx":3022
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31305,7 +31475,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3017
+/* "pywrapfst.pyx":3029
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31332,7 +31502,7 @@ 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, 3017, __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, 3029, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31348,10 +31518,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, 3017, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3029, __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, 3017, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3029, __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;
@@ -31370,7 +31540,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3026
+  /* "pywrapfst.pyx":3038
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -31379,12 +31549,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, 3026, __pyx_L1_error)
+    __PYX_ERR(0, 3038, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3017
+  /* "pywrapfst.pyx":3029
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31425,7 +31595,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __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, 3017, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_11ArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3029, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31442,7 +31612,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3028
+/* "pywrapfst.pyx":3040
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -31469,7 +31639,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(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_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3028, __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, 3040, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31485,10 +31655,10 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(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, 3028, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3040, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3028, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3040, __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;
@@ -31507,7 +31677,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":3037
+  /* "pywrapfst.pyx":3049
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -31516,12 +31686,12 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3037, __pyx_L1_error)
+    __PYX_ERR(0, 3049, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3028
+  /* "pywrapfst.pyx":3040
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -31562,7 +31732,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3028, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3040, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31579,7 +31749,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3039
+/* "pywrapfst.pyx":3051
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31604,7 +31774,7 @@ 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, 3039, __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, 3051, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31620,7 +31790,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, 3039, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3051, __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;
@@ -31640,7 +31810,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3045
+  /* "pywrapfst.pyx":3057
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -31649,11 +31819,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, 3045, __pyx_L1_error)
+    __PYX_ERR(0, 3057, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3039
+  /* "pywrapfst.pyx":3051
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31693,7 +31863,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 3039, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3051, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31710,7 +31880,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3047
+/* "pywrapfst.pyx":3059
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -31737,7 +31907,7 @@ 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, 3047, __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, 3059, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31753,10 +31923,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, 3047, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __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, 3047, __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, 3059, __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;
@@ -31775,7 +31945,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3056
+  /* "pywrapfst.pyx":3068
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -31784,12 +31954,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, 3056, __pyx_L1_error)
+    __PYX_ERR(0, 3068, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3047
+  /* "pywrapfst.pyx":3059
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -31830,7 +32000,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __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, 3047, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_11ArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3059, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31847,7 +32017,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3058
+/* "pywrapfst.pyx":3070
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -31872,7 +32042,7 @@ 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, 3058, __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, 3070, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -31888,7 +32058,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, 3058, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3070, __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;
@@ -31908,7 +32078,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     #endif
   }
 
-  /* "pywrapfst.pyx":3064
+  /* "pywrapfst.pyx":3076
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -31917,11 +32087,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, 3064, __pyx_L1_error)
+    __PYX_ERR(0, 3076, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3058
+  /* "pywrapfst.pyx":3070
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -31961,7 +32131,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3058, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3070, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31978,7 +32148,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3066
+/* "pywrapfst.pyx":3078
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -32004,10 +32174,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, 3066, __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, 3078, __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, 3066, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3078, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -32023,7 +32193,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, 3066, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3078, __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;
@@ -32043,7 +32213,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3075
+  /* "pywrapfst.pyx":3087
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -32052,11 +32222,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, 3075, __pyx_L1_error)
+    __PYX_ERR(0, 3087, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3066
+  /* "pywrapfst.pyx":3078
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -32086,7 +32256,7 @@ 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, 3066, __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, 3078, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -32107,7 +32277,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 3066, __pyx_L1_error)
+  __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, 3078, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32124,7 +32294,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3077
+/* "pywrapfst.pyx":3089
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -32153,12 +32323,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, 3077, __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, 3089, __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_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3077, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3089, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3077, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3089, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -32176,7 +32346,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, 3077, __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, 3089, __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;
@@ -32186,7 +32356,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, 3077, __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, 3089, __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;
@@ -32194,7 +32364,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, 3077, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3089, __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;
@@ -32205,7 +32375,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, 3077, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3089, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -32227,7 +32397,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":3087
+  /* "pywrapfst.pyx":3099
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -32236,11 +32406,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, 3087, __pyx_L1_error)
+    __PYX_ERR(0, 3099, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3077
+  /* "pywrapfst.pyx":3089
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -32295,11 +32465,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, 3077, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3089, __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, 3077, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3089, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32307,12 +32477,12 @@ 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_uint32_t(values[0]); if (unlikely((__pyx_v_flags == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3077, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3077, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint32_t(values[0]); if (unlikely((__pyx_v_flags == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3089, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3089, __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, 3077, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3089, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -32331,7 +32501,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   PyObject *__pyx_t_1 = NULL;
   __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, 3077, __pyx_L1_error)
+  __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, 3089, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32348,7 +32518,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3089
+/* "pywrapfst.pyx":3101
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32374,7 +32544,7 @@ 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, 3089, __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, 3101, __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)) {
         __Pyx_XDECREF(__pyx_r);
@@ -32391,7 +32561,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, 3089, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -32412,7 +32582,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3095
+  /* "pywrapfst.pyx":3107
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -32422,15 +32592,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, 3095, __pyx_L1_error)
+    __PYX_ERR(0, 3107, __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, 3095, __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, 3107, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3089
+  /* "pywrapfst.pyx":3101
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32472,7 +32642,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3089, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3101, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32596,7 +32766,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3107
+/* "pywrapfst.pyx":3119
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32626,7 +32796,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3108
+  /* "pywrapfst.pyx":3120
  * 
  *   def __repr__(self):
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -32634,9 +32804,9 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
  *   def __init__(self, _MutableFst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3108, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3120, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3108, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3120, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -32651,14 +32821,14 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3108, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3120, __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":3107
+  /* "pywrapfst.pyx":3119
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32680,7 +32850,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3110
+/* "pywrapfst.pyx":3122
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -32719,11 +32889,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, 3110, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3122, __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, 3110, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3122, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32732,17 +32902,17 @@ 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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3110, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3122, __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, 3110, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3122, __pyx_L3_error)
   __pyx_L3_error:;
   __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, 3110, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3122, __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);
 
   /* function exit code */
@@ -32764,7 +32934,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   std::shared_ptr<fst::script::MutableFstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3111
+  /* "pywrapfst.pyx":3123
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32773,19 +32943,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, 3111, __pyx_L1_error)
+    __PYX_ERR(0, 3123, __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":3112
+    /* "pywrapfst.pyx":3124
  *   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, 3112, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3124, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32799,14 +32969,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, 3112, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3124, __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, 3112, __pyx_L1_error)
+    __PYX_ERR(0, 3124, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3111
+    /* "pywrapfst.pyx":3123
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32815,7 +32985,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":3114
+  /* "pywrapfst.pyx":3126
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -32824,16 +32994,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, 3114, __pyx_L1_error)
+    __PYX_ERR(0, 3126, __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, 3114, __pyx_L1_error)
+    __PYX_ERR(0, 3126, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3115
+  /* "pywrapfst.pyx":3127
  *     # 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))             # <<<<<<<<<<<<<<
@@ -32842,15 +33012,15 @@ 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, 3115, __pyx_L1_error)
+    __PYX_ERR(0, 3127, __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, 3115, __pyx_L1_error)
+    __PYX_ERR(0, 3127, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3110
+  /* "pywrapfst.pyx":3122
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -32873,7 +33043,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
 }
 static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "pywrapfst.pyx":3118
+/* "pywrapfst.pyx":3130
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32903,7 +33073,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, 3118, __pyx_L1_error)
+    __PYX_ERR(0, 3130, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -32911,7 +33081,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, 3118, __pyx_L1_error)
+    __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, 3130, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -32943,9 +33113,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3118, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3130, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3119
+  /* "pywrapfst.pyx":3131
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):
  *     while not self.done():             # <<<<<<<<<<<<<<
@@ -32955,12 +33125,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, 3119, __pyx_L1_error)
+      __PYX_ERR(0, 3131, __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);
     if (!__pyx_t_1) break;
 
-    /* "pywrapfst.pyx":3120
+    /* "pywrapfst.pyx":3132
  *   def __iter__(self):
  *     while not self.done():
  *       yield self.value()             # <<<<<<<<<<<<<<
@@ -32969,9 +33139,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, 3120, __pyx_L1_error)
+      __PYX_ERR(0, 3132, __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, 3120, __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, 3132, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -32982,9 +33152,9 @@ 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, 3120, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3132, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3121
+    /* "pywrapfst.pyx":3133
  *     while not self.done():
  *       yield self.value()
  *       self.next()             # <<<<<<<<<<<<<<
@@ -32993,13 +33163,13 @@ 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'", "next");
-      __PYX_ERR(0, 3121, __pyx_L1_error)
+      __PYX_ERR(0, 3133, __pyx_L1_error)
     }
     ((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":3118
+  /* "pywrapfst.pyx":3130
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -33024,7 +33194,7 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3123
+/* "pywrapfst.pyx":3135
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -33051,7 +33221,7 @@ 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, 3123, __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, 3135, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33067,10 +33237,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, 3123, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3135, __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, 3123, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3135, __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;
@@ -33089,7 +33259,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3132
+  /* "pywrapfst.pyx":3144
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -33098,12 +33268,12 @@ 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, 3132, __pyx_L1_error)
+    __PYX_ERR(0, 3144, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3123
+  /* "pywrapfst.pyx":3135
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -33144,7 +33314,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   PyObject *__pyx_t_1 = NULL;
   __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, 3123, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_18MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3135, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33161,7 +33331,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3134
+/* "pywrapfst.pyx":3146
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -33188,7 +33358,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
     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, 3134, __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, 3146, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33204,10 +33374,10 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
         }
         __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, 3134, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3146, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3134, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3146, __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;
@@ -33226,7 +33396,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
     #endif
   }
 
-  /* "pywrapfst.pyx":3143
+  /* "pywrapfst.pyx":3155
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -33235,12 +33405,12 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3143, __pyx_L1_error)
+    __PYX_ERR(0, 3155, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3134
+  /* "pywrapfst.pyx":3146
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -33281,7 +33451,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3134, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33298,7 +33468,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3145
+/* "pywrapfst.pyx":3157
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33323,7 +33493,7 @@ 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, 3145, __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, 3157, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33339,7 +33509,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, 3145, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3157, __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;
@@ -33359,7 +33529,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3151
+  /* "pywrapfst.pyx":3163
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -33368,11 +33538,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, 3151, __pyx_L1_error)
+    __PYX_ERR(0, 3163, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3145
+  /* "pywrapfst.pyx":3157
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33412,7 +33582,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 3145, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3157, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33429,7 +33599,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3153
+/* "pywrapfst.pyx":3165
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33456,7 +33626,7 @@ 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, 3153, __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, 3165, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33472,10 +33642,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, 3153, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3165, __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, 3153, __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, 3165, __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;
@@ -33494,7 +33664,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3162
+  /* "pywrapfst.pyx":3174
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -33503,12 +33673,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, 3162, __pyx_L1_error)
+    __PYX_ERR(0, 3174, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3153
+  /* "pywrapfst.pyx":3165
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33549,7 +33719,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   PyObject *__pyx_t_1 = NULL;
   __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, 3153, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_18MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3165, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33566,7 +33736,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3164
+/* "pywrapfst.pyx":3176
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33591,7 +33761,7 @@ 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, 3164, __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, 3176, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33607,7 +33777,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, 3164, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3176, __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;
@@ -33627,7 +33797,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":3170
+  /* "pywrapfst.pyx":3182
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -33636,11 +33806,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, 3170, __pyx_L1_error)
+    __PYX_ERR(0, 3182, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3164
+  /* "pywrapfst.pyx":3176
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33680,7 +33850,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __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, 3164, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3176, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33697,7 +33867,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3172
+/* "pywrapfst.pyx":3184
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33723,10 +33893,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, 3172, __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, 3184, __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, 3172, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3184, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33742,7 +33912,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, 3172, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3184, __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;
@@ -33762,7 +33932,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3181
+  /* "pywrapfst.pyx":3193
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -33771,11 +33941,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, 3181, __pyx_L1_error)
+    __PYX_ERR(0, 3193, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3172
+  /* "pywrapfst.pyx":3184
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33805,7 +33975,7 @@ 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, 3172, __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, 3184, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -33826,7 +33996,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 3172, __pyx_L1_error)
+  __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, 3184, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33843,7 +34013,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3183
+/* "pywrapfst.pyx":3195
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -33872,12 +34042,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, 3183, __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, 3195, __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_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3183, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3195, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3183, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3195, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -33895,7 +34065,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, 3183, __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, 3195, __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;
@@ -33905,7 +34075,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, 3183, __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, 3195, __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;
@@ -33913,7 +34083,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, 3183, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3195, __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;
@@ -33924,7 +34094,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, 3183, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3195, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -33946,7 +34116,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3193
+  /* "pywrapfst.pyx":3205
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -33955,11 +34125,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, 3193, __pyx_L1_error)
+    __PYX_ERR(0, 3205, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3183
+  /* "pywrapfst.pyx":3195
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -34014,11 +34184,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, 3183, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3195, __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, 3183, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3195, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -34026,12 +34196,12 @@ 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_uint32_t(values[0]); if (unlikely((__pyx_v_flags == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3183, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3183, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint32_t(values[0]); if (unlikely((__pyx_v_flags == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3195, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint32_t(values[1]); if (unlikely((__pyx_v_mask == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3195, __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, 3183, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3195, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -34050,7 +34220,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   PyObject *__pyx_t_1 = NULL;
   __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, 3183, __pyx_L1_error)
+  __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, 3195, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34067,7 +34237,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3195
+/* "pywrapfst.pyx":3207
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -34092,7 +34262,7 @@ 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, 3195, __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, 3207, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34108,7 +34278,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, 3195, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3207, __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;
@@ -34128,7 +34298,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3204
+  /* "pywrapfst.pyx":3216
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -34137,15 +34307,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, 3204, __pyx_L1_error)
+    __PYX_ERR(0, 3216, __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, 3204, __pyx_L1_error)
+    __PYX_ERR(0, 3216, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3195
+  /* "pywrapfst.pyx":3207
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -34172,7 +34342,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *
   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, 3195, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3207, __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));
 
   /* function exit code */
@@ -34190,7 +34360,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   PyObject *__pyx_t_1 = NULL;
   __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, 3195, __pyx_L1_error)
+  __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, 3207, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34207,7 +34377,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3206
+/* "pywrapfst.pyx":3218
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34233,7 +34403,7 @@ 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, 3206, __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, 3218, __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)) {
         __Pyx_XDECREF(__pyx_r);
@@ -34250,7 +34420,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, 3206, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3218, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -34271,7 +34441,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3212
+  /* "pywrapfst.pyx":3224
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -34281,15 +34451,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, 3212, __pyx_L1_error)
+    __PYX_ERR(0, 3224, __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, 3212, __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, 3224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3206
+  /* "pywrapfst.pyx":3218
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34331,7 +34501,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __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, 3206, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3218, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34455,7 +34625,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3226
+/* "pywrapfst.pyx":3238
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34485,7 +34655,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3227
+  /* "pywrapfst.pyx":3239
  * 
  *   def __repr__(self):
  *     return "<StateIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -34493,9 +34663,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
  *   def __init__(self, _Fst ifst):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3227, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3239, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3227, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3239, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -34510,14 +34680,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3227, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3239, __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":3226
+  /* "pywrapfst.pyx":3238
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34539,7 +34709,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3229
+/* "pywrapfst.pyx":3241
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34573,7 +34743,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, 3229, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3241, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -34584,13 +34754,13 @@ 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, 3229, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3241, __pyx_L3_error)
   __pyx_L3_error:;
   __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, 3229, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3241, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_2__init__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self), __pyx_v_ifst);
 
   /* function exit code */
@@ -34608,7 +34778,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   std::shared_ptr<fst::script::FstClass>  __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3231
+  /* "pywrapfst.pyx":3243
  *   def __init__(self, _Fst ifst):
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -34617,16 +34787,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, 3231, __pyx_L1_error)
+    __PYX_ERR(0, 3243, __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, 3231, __pyx_L1_error)
+    __PYX_ERR(0, 3243, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3232
+  /* "pywrapfst.pyx":3244
  *     # 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)))             # <<<<<<<<<<<<<<
@@ -34635,15 +34805,15 @@ 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, 3232, __pyx_L1_error)
+    __PYX_ERR(0, 3244, __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, 3232, __pyx_L1_error)
+    __PYX_ERR(0, 3244, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3229
+  /* "pywrapfst.pyx":3241
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34662,7 +34832,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3235
+/* "pywrapfst.pyx":3247
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34688,7 +34858,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3236
+  /* "pywrapfst.pyx":3248
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -34700,7 +34870,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3235
+  /* "pywrapfst.pyx":3247
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34715,7 +34885,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3239
+/* "pywrapfst.pyx":3251
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -34744,7 +34914,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3240
+  /* "pywrapfst.pyx":3252
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34753,12 +34923,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, 3240, __pyx_L1_error)
+    __PYX_ERR(0, 3252, __pyx_L1_error)
   }
   __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":3241
+    /* "pywrapfst.pyx":3253
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -34766,9 +34936,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, 3241, __pyx_L1_error)
+    __PYX_ERR(0, 3253, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3240
+    /* "pywrapfst.pyx":3252
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34777,7 +34947,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3242
+  /* "pywrapfst.pyx":3254
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -34786,11 +34956,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, 3242, __pyx_L1_error)
+    __PYX_ERR(0, 3254, __pyx_L1_error)
   }
   __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3243
+  /* "pywrapfst.pyx":3255
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -34799,11 +34969,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, 3243, __pyx_L1_error)
+    __PYX_ERR(0, 3255, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3244
+  /* "pywrapfst.pyx":3256
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -34811,13 +34981,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, 3244, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3256, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3239
+  /* "pywrapfst.pyx":3251
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -34836,7 +35006,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3246
+/* "pywrapfst.pyx":3258
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34863,7 +35033,7 @@ 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, 3246, __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, 3258, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34879,10 +35049,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, 3246, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3258, __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, 3246, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __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;
@@ -34901,7 +35071,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3255
+  /* "pywrapfst.pyx":3267
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -34910,12 +35080,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, 3255, __pyx_L1_error)
+    __PYX_ERR(0, 3267, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3246
+  /* "pywrapfst.pyx":3258
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34956,7 +35126,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3246, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_13StateIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3258, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34973,7 +35143,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3257
+/* "pywrapfst.pyx":3269
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34998,7 +35168,7 @@ 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, 3257, __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, 3269, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35014,7 +35184,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, 3257, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3269, __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;
@@ -35034,7 +35204,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3263
+  /* "pywrapfst.pyx":3275
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -35043,11 +35213,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, 3263, __pyx_L1_error)
+    __PYX_ERR(0, 3275, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3257
+  /* "pywrapfst.pyx":3269
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -35087,7 +35257,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __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, 3257, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3269, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35104,7 +35274,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3265
+/* "pywrapfst.pyx":3277
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35129,7 +35299,7 @@ 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, 3265, __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, 3277, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35145,7 +35315,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, 3265, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3277, __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;
@@ -35165,7 +35335,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":3271
+  /* "pywrapfst.pyx":3283
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -35174,11 +35344,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, 3271, __pyx_L1_error)
+    __PYX_ERR(0, 3283, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3265
+  /* "pywrapfst.pyx":3277
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35218,7 +35388,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __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, 3265, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3277, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35235,7 +35405,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3273
+/* "pywrapfst.pyx":3285
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35262,7 +35432,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(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_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3273, __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, 3285, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35278,10 +35448,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(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, 3273, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3285, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3273, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3285, __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;
@@ -35300,7 +35470,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":3279
+  /* "pywrapfst.pyx":3291
  *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -35309,12 +35479,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3279, __pyx_L1_error)
+    __PYX_ERR(0, 3291, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3273
+  /* "pywrapfst.pyx":3285
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35355,7 +35525,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __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, 3273, __pyx_L1_error)
+  __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, 3285, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35479,7 +35649,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3285
+/* "pywrapfst.pyx":3297
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35492,7 +35662,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3289
+  /* "pywrapfst.pyx":3301
  *                map_type=b"identity",
  *                double power=1.,
  *                weight=None):             # <<<<<<<<<<<<<<
@@ -35529,27 +35699,27 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
   }
 
-  /* "pywrapfst.pyx":3291
+  /* "pywrapfst.pyx":3303
  *                weight=None):
  *   cdef fst.MapType map_type_enum
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3291, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3303, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v_map_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3292
+    /* "pywrapfst.pyx":3304
  *   cdef fst.MapType map_type_enum
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))             # <<<<<<<<<<<<<<
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
  *       weight) if map_type_enum == fst.TIMES_MAPPER else
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3292, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3304, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3292, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3304, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -35563,7 +35733,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_map_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_map_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3292, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3304, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -35579,14 +35749,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3292, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3304, __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, 3292, __pyx_L1_error)
+    __PYX_ERR(0, 3304, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3291
+    /* "pywrapfst.pyx":3303
  *                weight=None):
  *   cdef fst.MapType map_type_enum
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
@@ -35595,7 +35765,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":3294
+  /* "pywrapfst.pyx":3306
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
  *       weight) if map_type_enum == fst.TIMES_MAPPER else             # <<<<<<<<<<<<<<
@@ -35604,7 +35774,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
   if (((__pyx_v_map_type_enum == fst::script::TIMES_MAPPER) != 0)) {
 
-    /* "pywrapfst.pyx":3293
+    /* "pywrapfst.pyx":3305
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -35613,21 +35783,21 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3293, __pyx_L1_error)
+      __PYX_ERR(0, 3305, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3294
+    /* "pywrapfst.pyx":3306
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
  *       weight) if map_type_enum == fst.TIMES_MAPPER else             # <<<<<<<<<<<<<<
  *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
  *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
  */
-    __pyx_t_9 = __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, 3293, __pyx_L1_error)
+    __pyx_t_9 = __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, 3305, __pyx_L1_error)
     __pyx_t_8 = __pyx_t_9;
   } else {
 
-    /* "pywrapfst.pyx":3295
+    /* "pywrapfst.pyx":3307
  *   cdef fst.WeightClass wc = (_get_WeightClass_or_One(ifst.weight_type(),
  *       weight) if map_type_enum == fst.TIMES_MAPPER else
  *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))             # <<<<<<<<<<<<<<
@@ -35636,14 +35806,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3295, __pyx_L1_error)
+      __PYX_ERR(0, 3307, __pyx_L1_error)
     }
-    __pyx_t_9 = __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, 3295, __pyx_L1_error)
+    __pyx_t_9 = __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, 3307, __pyx_L1_error)
     __pyx_t_8 = __pyx_t_9;
   }
   __pyx_v_wc = __pyx_t_8;
 
-  /* "pywrapfst.pyx":3296
+  /* "pywrapfst.pyx":3308
  *       weight) if map_type_enum == fst.TIMES_MAPPER else
  *       _get_WeightClass_or_Zero(ifst.weight_type(), weight))
  *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))             # <<<<<<<<<<<<<<
@@ -35653,15 +35823,15 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3296, __pyx_L1_error)
+    __PYX_ERR(0, 3308, __pyx_L1_error)
   }
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v_map_type_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3296, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v_map_type_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3308, __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":3285
+  /* "pywrapfst.pyx":3297
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35684,7 +35854,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3299
+/* "pywrapfst.pyx":3311
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35698,7 +35868,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3303
+  /* "pywrapfst.pyx":3315
  *                   map_type=b"identity",
  *                   double power=1.,
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -35726,7 +35896,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3346
+  /* "pywrapfst.pyx":3358
  *   See also: `statemap`.
  *   """
  *   return _map(ifst, delta, map_type, power, weight)             # <<<<<<<<<<<<<<
@@ -35739,13 +35909,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
   __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, 3346, __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, 3358, __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":3299
+  /* "pywrapfst.pyx":3311
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35781,7 +35951,7 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(PyObject *__pyx_self, PyObject *__
     PyObject* values[5] = {0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_identity);
 
-    /* "pywrapfst.pyx":3303
+    /* "pywrapfst.pyx":3315
  *                   map_type=b"identity",
  *                   double power=1.,
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -35837,7 +36007,7 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(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, 3299, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3311, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -35856,13 +36026,13 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(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, 3300, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3312, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__32;
     }
     __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, 3302, __pyx_L3_error)
+      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3314, __pyx_L3_error)
     } else {
       __pyx_v_power = ((double)1.);
     }
@@ -35870,16 +36040,16 @@ static PyObject *__pyx_pw_9pywrapfst_19arcmap(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, 3299, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3311, __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, 3299, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3311, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_18arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_power, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3299
+  /* "pywrapfst.pyx":3311
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35908,7 +36078,7 @@ static PyObject *__pyx_pf_9pywrapfst_18arcmap(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, 3299, __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, 3311, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35925,7 +36095,7 @@ static PyObject *__pyx_pf_9pywrapfst_18arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3349
+/* "pywrapfst.pyx":3361
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -35937,7 +36107,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(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_b_auto);
 
-  /* "pywrapfst.pyx":3352
+  /* "pywrapfst.pyx":3364
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -35962,7 +36132,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
     }
   }
 
-  /* "pywrapfst.pyx":3378
+  /* "pywrapfst.pyx":3390
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -35971,21 +36141,21 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3378, __pyx_L1_error)
+    __PYX_ERR(0, 3390, __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":3381
+  /* "pywrapfst.pyx":3393
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   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, 3381, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3381, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3393, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3393, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3380
+  /* "pywrapfst.pyx":3392
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
@@ -35994,7 +36164,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3382
+  /* "pywrapfst.pyx":3394
  *   opts.reset(new fst.ComposeOptions(connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -36003,15 +36173,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3382, __pyx_L1_error)
+    __PYX_ERR(0, 3394, __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, 3382, __pyx_L1_error)
+    __PYX_ERR(0, 3394, __pyx_L1_error)
   }
   fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3383
+  /* "pywrapfst.pyx":3395
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36019,13 +36189,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  * 
  */
   __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, 3383, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3395, __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":3349
+  /* "pywrapfst.pyx":3361
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36083,7 +36253,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(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, 3349, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3361, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -36099,7 +36269,7 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(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, 3349, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3361, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36117,10 +36287,10 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(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, 3352, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3364, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3352
+      /* "pywrapfst.pyx":3364
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -36132,17 +36302,17 @@ static PyObject *__pyx_pw_9pywrapfst_21compose(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, 3349, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3361, __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, 3349, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3350, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3361, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3362, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_20compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3349
+  /* "pywrapfst.pyx":3361
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36169,7 +36339,7 @@ static PyObject *__pyx_pf_9pywrapfst_20compose(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, 3349, __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, 3361, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36186,7 +36356,7 @@ static PyObject *__pyx_pf_9pywrapfst_20compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3386
+/* "pywrapfst.pyx":3398
  * 
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
@@ -36215,17 +36385,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
   }
 
-  /* "pywrapfst.pyx":3403
+  /* "pywrapfst.pyx":3415
  *     FstOpError: Conversion failed.
  *   """
  *   cdef string fst_type_string = tostring(fst_type)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3403, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3415, __pyx_L1_error)
   __pyx_v_fst_type_string = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3405
+  /* "pywrapfst.pyx":3417
  *   cdef string fst_type_string = tostring(fst_type)
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))             # <<<<<<<<<<<<<<
@@ -36234,11 +36404,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3405, __pyx_L1_error)
+    __PYX_ERR(0, 3417, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v_fst_type_string));
 
-  /* "pywrapfst.pyx":3407
+  /* "pywrapfst.pyx":3419
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -36248,16 +36418,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":3408
+    /* "pywrapfst.pyx":3420
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3408, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3420, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3408, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3420, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -36271,7 +36441,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
     __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_fst_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_fst_type);
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3408, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3420, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -36287,14 +36457,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3408, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3420, __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, 3408, __pyx_L1_error)
+    __PYX_ERR(0, 3420, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3407
+    /* "pywrapfst.pyx":3419
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -36303,7 +36473,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":3409
+  /* "pywrapfst.pyx":3421
  *   if tfst.get() == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36311,13 +36481,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, 3409, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3421, __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":3386
+  /* "pywrapfst.pyx":3398
  * 
  * 
  * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
@@ -36377,7 +36547,7 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(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, 3386, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3398, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36393,13 +36563,13 @@ static PyObject *__pyx_pw_9pywrapfst_23convert(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, 3386, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3398, __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, 3386, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3398, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_22convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
@@ -36420,7 +36590,7 @@ static PyObject *__pyx_pf_9pywrapfst_22convert(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, 3386, __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, 3398, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36437,7 +36607,7 @@ static PyObject *__pyx_pf_9pywrapfst_22convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3412
+/* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36452,7 +36622,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__34;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3417
+  /* "pywrapfst.pyx":3429
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36461,7 +36631,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3418
+  /* "pywrapfst.pyx":3430
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36505,7 +36675,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
   }
 
-  /* "pywrapfst.pyx":3454
+  /* "pywrapfst.pyx":3466
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -36514,11 +36684,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3454, __pyx_L1_error)
+    __PYX_ERR(0, 3466, __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":3456
+  /* "pywrapfst.pyx":3468
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -36527,29 +36697,29 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3456, __pyx_L1_error)
+    __PYX_ERR(0, 3468, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3457
+  /* "pywrapfst.pyx":3469
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
  *                                                      weight)             # <<<<<<<<<<<<<<
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(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, 3456, __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, 3468, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3459
+  /* "pywrapfst.pyx":3471
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
  *                                 addr(determinize_type_enum)):
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3459, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3471, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3460
+  /* "pywrapfst.pyx":3472
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),
  *                                 addr(determinize_type_enum)):             # <<<<<<<<<<<<<<
@@ -36558,7 +36728,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   __pyx_t_3 = ((!(fst::script::GetDeterminizeType(__pyx_t_2, (&__pyx_v_determinize_type_enum)) != 0)) != 0);
 
-  /* "pywrapfst.pyx":3459
+  /* "pywrapfst.pyx":3471
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36567,16 +36737,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":3461
+    /* "pywrapfst.pyx":3473
  *   if not fst.GetDeterminizeType(tostring(det_type),
  *                                 addr(determinize_type_enum)):
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.DeterminizeOptions] opts
  *   opts.reset(new fst.DeterminizeOptions(delta, wc, nstate, subsequential_label,
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3461, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3461, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -36590,7 +36760,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
     __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_det_type) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_det_type);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3461, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -36606,14 +36776,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     __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, 3461, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3473, __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, 3461, __pyx_L1_error)
+    __PYX_ERR(0, 3473, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3459
+    /* "pywrapfst.pyx":3471
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36622,7 +36792,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   }
 
-  /* "pywrapfst.pyx":3463
+  /* "pywrapfst.pyx":3475
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
  *   cdef unique_ptr[fst.DeterminizeOptions] opts
  *   opts.reset(new fst.DeterminizeOptions(delta, wc, nstate, subsequential_label,             # <<<<<<<<<<<<<<
@@ -36631,7 +36801,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   __pyx_v_opts.reset(new fst::script::DeterminizeOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_determinize_type_enum, __pyx_v_increment_subsequential_label));
 
-  /* "pywrapfst.pyx":3466
+  /* "pywrapfst.pyx":3478
  *                                         determinize_type_enum,
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -36640,11 +36810,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3466, __pyx_L1_error)
+    __PYX_ERR(0, 3478, __pyx_L1_error)
   }
   fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3467
+  /* "pywrapfst.pyx":3479
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36652,13 +36822,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(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, 3467, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3479, __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":3412
+  /* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36700,7 +36870,7 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(PyObject *__pyx_self, PyObjec
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_functional);
 
-    /* "pywrapfst.pyx":3417
+    /* "pywrapfst.pyx":3429
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36772,7 +36942,7 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(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, 3412, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3424, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36795,27 +36965,27 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(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, 3413, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3425, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__33;
     }
     __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3415, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3427, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__34;
     }
     if (values[4]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3416, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3428, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((__pyx_t_10basictypes_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, 3418, __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, 3430, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3418
+      /* "pywrapfst.pyx":3430
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36827,16 +36997,16 @@ static PyObject *__pyx_pw_9pywrapfst_25determinize(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, 3412, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3424, __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, 3412, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3424, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_24determinize(__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":3412
+  /* "pywrapfst.pyx":3424
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36867,7 +37037,7 @@ static PyObject *__pyx_pf_9pywrapfst_24determinize(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, 3412, __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, 3424, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36884,7 +37054,7 @@ static PyObject *__pyx_pf_9pywrapfst_24determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3470
+/* "pywrapfst.pyx":3482
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36896,7 +37066,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(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_b_auto);
 
-  /* "pywrapfst.pyx":3473
+  /* "pywrapfst.pyx":3485
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -36921,7 +37091,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
     }
   }
 
-  /* "pywrapfst.pyx":3498
+  /* "pywrapfst.pyx":3510
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -36930,30 +37100,30 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3498, __pyx_L1_error)
+    __PYX_ERR(0, 3510, __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":3501
+  /* "pywrapfst.pyx":3513
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
  *       tostring(compose_filter))))             # <<<<<<<<<<<<<<
  *   fst.Difference(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, 3501, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3513, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3500
+  /* "pywrapfst.pyx":3512
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(             # <<<<<<<<<<<<<<
  *       tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3500, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3512, __pyx_L1_error)
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3502
+  /* "pywrapfst.pyx":3514
  *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
  *       tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -36962,15 +37132,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3502, __pyx_L1_error)
+    __PYX_ERR(0, 3514, __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, 3502, __pyx_L1_error)
+    __PYX_ERR(0, 3514, __pyx_L1_error)
   }
   fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3503
+  /* "pywrapfst.pyx":3515
  *       tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -36978,13 +37148,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  * 
  */
   __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, 3503, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3515, __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":3470
+  /* "pywrapfst.pyx":3482
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37042,7 +37212,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(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, 3470, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3482, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37058,7 +37228,7 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(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, 3470, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3482, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37076,10 +37246,10 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(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, 3473, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3485, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3473
+      /* "pywrapfst.pyx":3485
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -37091,17 +37261,17 @@ static PyObject *__pyx_pw_9pywrapfst_27difference(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, 3470, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3482, __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, 3470, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3471, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3482, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3483, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_26difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3470
+  /* "pywrapfst.pyx":3482
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37128,7 +37298,7 @@ static PyObject *__pyx_pf_9pywrapfst_26difference(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, 3470, __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, 3482, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37145,7 +37315,7 @@ static PyObject *__pyx_pf_9pywrapfst_26difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3506
+/* "pywrapfst.pyx":3518
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37159,7 +37329,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__36;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3510
+  /* "pywrapfst.pyx":3522
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -37190,7 +37360,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
     }
   }
 
-  /* "pywrapfst.pyx":3537
+  /* "pywrapfst.pyx":3549
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -37199,11 +37369,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3537, __pyx_L1_error)
+    __PYX_ERR(0, 3549, __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":3539
+  /* "pywrapfst.pyx":3551
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
@@ -37212,20 +37382,20 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3539, __pyx_L1_error)
+    __PYX_ERR(0, 3551, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3540
+  /* "pywrapfst.pyx":3552
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
  *                                                      weight)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.DisambiguateOptions] opts
  *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,
  */
-  __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, 3539, __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, 3551, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3542
+  /* "pywrapfst.pyx":3554
  *                                                      weight)
  *   cdef unique_ptr[fst.DisambiguateOptions] opts
  *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,             # <<<<<<<<<<<<<<
@@ -37234,7 +37404,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   __pyx_v_opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label));
 
-  /* "pywrapfst.pyx":3544
+  /* "pywrapfst.pyx":3556
  *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -37243,11 +37413,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3544, __pyx_L1_error)
+    __PYX_ERR(0, 3556, __pyx_L1_error)
   }
   fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3545
+  /* "pywrapfst.pyx":3557
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -37255,13 +37425,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  * 
  */
   __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, 3545, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3557, __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":3506
+  /* "pywrapfst.pyx":3518
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37296,7 +37466,7 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(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":3510
+    /* "pywrapfst.pyx":3522
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -37352,7 +37522,7 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(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, 3506, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3518, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37371,17 +37541,17 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(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, 3507, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3519, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__35;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3508, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3520, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__36;
     }
     if (values[3]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3509, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3521, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
     }
@@ -37389,16 +37559,16 @@ static PyObject *__pyx_pw_9pywrapfst_29disambiguate(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, 3506, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3518, __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, 3506, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3518, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_28disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3506
+  /* "pywrapfst.pyx":3518
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37427,7 +37597,7 @@ static PyObject *__pyx_pf_9pywrapfst_28disambiguate(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, 3506, __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, 3518, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37444,7 +37614,7 @@ static PyObject *__pyx_pf_9pywrapfst_28disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3548
+/* "pywrapfst.pyx":3560
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37467,7 +37637,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     }
   }
 
-  /* "pywrapfst.pyx":3571
+  /* "pywrapfst.pyx":3583
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -37476,11 +37646,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3571, __pyx_L1_error)
+    __PYX_ERR(0, 3583, __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":3572
+  /* "pywrapfst.pyx":3584
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37489,10 +37659,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3572, __pyx_L1_error)
+    __PYX_ERR(0, 3584, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3573
+  /* "pywrapfst.pyx":3585
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
  *                                                  eps_norm_output else             # <<<<<<<<<<<<<<
@@ -37501,7 +37671,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if ((__pyx_v_eps_norm_output != 0)) {
 
-    /* "pywrapfst.pyx":3572
+    /* "pywrapfst.pyx":3584
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37511,7 +37681,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     __pyx_t_1 = fst::EPS_NORM_OUTPUT;
   } else {
 
-    /* "pywrapfst.pyx":3574
+    /* "pywrapfst.pyx":3586
  *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if
  *                                                  eps_norm_output else
  *                                                  fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
@@ -37521,7 +37691,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3572
+  /* "pywrapfst.pyx":3584
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(deref(ifst._fst), tfst.get(), fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37530,7 +37700,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_t_1);
 
-  /* "pywrapfst.pyx":3575
+  /* "pywrapfst.pyx":3587
  *                                                  eps_norm_output else
  *                                                  fst.EPS_NORM_INPUT)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -37538,13 +37708,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  * 
  */
   __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, 3575, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3587, __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":3548
+  /* "pywrapfst.pyx":3560
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37599,7 +37769,7 @@ static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(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, 3548, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3560, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37612,20 +37782,20 @@ static PyObject *__pyx_pw_9pywrapfst_31epsnormalize(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, 3548, __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, 3560, __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, 3548, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3560, __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, 3548, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3560, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_30epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
@@ -37646,7 +37816,7 @@ static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(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, 3548, __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, 3560, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37663,7 +37833,7 @@ static PyObject *__pyx_pf_9pywrapfst_30epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3578
+/* "pywrapfst.pyx":3590
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37683,7 +37853,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
     }
   }
 
-  /* "pywrapfst.pyx":3598
+  /* "pywrapfst.pyx":3610
  *   See also: `equivalent`, `isomorphic`, `randequivalent`.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -37692,16 +37862,16 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3598, __pyx_L1_error)
+    __PYX_ERR(0, 3610, __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, 3598, __pyx_L1_error)
+    __PYX_ERR(0, 3610, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3578
+  /* "pywrapfst.pyx":3590
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37753,7 +37923,7 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(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, 3578, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3590, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37763,7 +37933,7 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(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, 3578, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3590, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37778,21 +37948,21 @@ static PyObject *__pyx_pw_9pywrapfst_33equal(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, 3578, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3590, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__37;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3578, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3590, __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, 3578, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3578, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3590, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3590, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_32equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -37815,7 +37985,7 @@ static PyObject *__pyx_pf_9pywrapfst_32equal(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, 3578, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3590, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -37832,7 +38002,7 @@ static PyObject *__pyx_pf_9pywrapfst_32equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3601
+/* "pywrapfst.pyx":3613
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -37852,7 +38022,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3621
+  /* "pywrapfst.pyx":3633
  *   See also: `equal`, `isomorphic`, `randequivalent`.
  *   """
  *   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -37861,16 +38031,16 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3621, __pyx_L1_error)
+    __PYX_ERR(0, 3633, __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, 3621, __pyx_L1_error)
+    __PYX_ERR(0, 3633, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3601
+  /* "pywrapfst.pyx":3613
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -37922,7 +38092,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(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, 3601, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3613, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37932,7 +38102,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(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, 3601, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3613, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37947,21 +38117,21 @@ static PyObject *__pyx_pw_9pywrapfst_35equivalent(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, 3601, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3613, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__38;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3601, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3613, __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, 3601, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3601, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3613, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3613, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_34equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -37983,8 +38153,8 @@ static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_
   __Pyx_XDECREF(__pyx_r);
   __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); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3601, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3601, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3613, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3613, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38001,7 +38171,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3624
+/* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38013,7 +38183,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(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_b_auto);
 
-  /* "pywrapfst.pyx":3627
+  /* "pywrapfst.pyx":3639
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38038,7 +38208,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
     }
   }
 
-  /* "pywrapfst.pyx":3650
+  /* "pywrapfst.pyx":3662
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -38047,21 +38217,21 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(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, 3662, __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":3653
+  /* "pywrapfst.pyx":3665
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   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, 3653, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3653, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3665, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3665, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3652
+  /* "pywrapfst.pyx":3664
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
@@ -38070,7 +38240,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3654
+  /* "pywrapfst.pyx":3666
  *   opts.reset(new fst.ComposeOptions(connect,
  *         _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -38079,15 +38249,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3654, __pyx_L1_error)
+    __PYX_ERR(0, 3666, __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, 3654, __pyx_L1_error)
+    __PYX_ERR(0, 3666, __pyx_L1_error)
   }
   fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3655
+  /* "pywrapfst.pyx":3667
  *         _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38095,13 +38265,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(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, 3655, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3667, __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":3624
+  /* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38159,7 +38329,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(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, 3624, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3636, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38175,7 +38345,7 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(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, 3624, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3636, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38193,10 +38363,10 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(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, 3627, __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":3627
+      /* "pywrapfst.pyx":3639
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -38208,17 +38378,17 @@ static PyObject *__pyx_pw_9pywrapfst_37intersect(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, 3624, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3636, __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, 3624, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3625, __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_36intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3624
+  /* "pywrapfst.pyx":3636
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38245,7 +38415,7 @@ static PyObject *__pyx_pf_9pywrapfst_36intersect(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, 3624, __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, 3636, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38262,7 +38432,7 @@ static PyObject *__pyx_pf_9pywrapfst_36intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3658
+/* "pywrapfst.pyx":3670
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38282,7 +38452,7 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3681
+  /* "pywrapfst.pyx":3693
  *   See also: `equal`, `equivalent`, `randequivalent`.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -38291,16 +38461,16 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3681, __pyx_L1_error)
+    __PYX_ERR(0, 3693, __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, 3681, __pyx_L1_error)
+    __PYX_ERR(0, 3693, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3658
+  /* "pywrapfst.pyx":3670
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38352,7 +38522,7 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(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, 3658, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3670, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38362,7 +38532,7 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(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, 3658, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3670, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38377,21 +38547,21 @@ static PyObject *__pyx_pw_9pywrapfst_39isomorphic(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, 3658, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3670, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__39;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3658, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3670, __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, 3658, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3658, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3670, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3670, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_38isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -38414,7 +38584,7 @@ static PyObject *__pyx_pf_9pywrapfst_38isomorphic(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, 3658, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3670, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38431,7 +38601,7 @@ static PyObject *__pyx_pf_9pywrapfst_38isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3684
+/* "pywrapfst.pyx":3696
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38444,7 +38614,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
   float __pyx_v_delta = __pyx_k__40;
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__41;
 
-  /* "pywrapfst.pyx":3687
+  /* "pywrapfst.pyx":3699
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38471,7 +38641,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
     }
   }
 
-  /* "pywrapfst.pyx":3711
+  /* "pywrapfst.pyx":3723
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38480,11 +38650,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, 3711, __pyx_L1_error)
+    __PYX_ERR(0, 3723, __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":3712
+  /* "pywrapfst.pyx":3724
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -38493,12 +38663,12 @@ 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, 3712, __pyx_L1_error)
+    __PYX_ERR(0, 3724, __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, 3712, __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, 3724, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3713
+  /* "pywrapfst.pyx":3725
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -38507,11 +38677,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, 3713, __pyx_L1_error)
+    __PYX_ERR(0, 3725, __pyx_L1_error)
   }
   fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3714
+  /* "pywrapfst.pyx":3726
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38519,13 +38689,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, 3714, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3726, __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":3684
+  /* "pywrapfst.pyx":3696
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38559,7 +38729,7 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(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":3687
+    /* "pywrapfst.pyx":3699
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38607,7 +38777,7 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(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, 3684, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3696, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38624,12 +38794,12 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(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, 3685, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3697, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__40;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3686, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3698, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__41;
     }
@@ -38637,16 +38807,16 @@ static PyObject *__pyx_pw_9pywrapfst_41prune(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, 3684, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3696, __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, 3684, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3696, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_40prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3684
+  /* "pywrapfst.pyx":3696
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38674,7 +38844,7 @@ static PyObject *__pyx_pf_9pywrapfst_40prune(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, 3684, __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, 3696, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38691,7 +38861,7 @@ static PyObject *__pyx_pf_9pywrapfst_40prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3717
+/* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38703,7 +38873,7 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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__42;
 
-  /* "pywrapfst.pyx":3719
+  /* "pywrapfst.pyx":3731
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -38712,7 +38882,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3720
+  /* "pywrapfst.pyx":3732
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -38721,7 +38891,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3721
+  /* "pywrapfst.pyx":3733
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -38730,7 +38900,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3722
+  /* "pywrapfst.pyx":3734
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -38739,7 +38909,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3723
+  /* "pywrapfst.pyx":3735
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -38774,7 +38944,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3763
+  /* "pywrapfst.pyx":3775
  *   # This is copied, almost verbatim, from nlp/fst/bin/fstpush.cc.
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38783,11 +38953,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, 3763, __pyx_L1_error)
+    __PYX_ERR(0, 3775, __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":3764
+  /* "pywrapfst.pyx":3776
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,             # <<<<<<<<<<<<<<
@@ -38796,7 +38966,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":3766
+  /* "pywrapfst.pyx":3778
  *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,
  *                                        remove_common_affix, remove_total_weight)
  *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),             # <<<<<<<<<<<<<<
@@ -38805,10 +38975,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, 3766, __pyx_L1_error)
+    __PYX_ERR(0, 3778, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3767
+  /* "pywrapfst.pyx":3779
  *                                        remove_common_affix, remove_total_weight)
  *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
  *            delta)             # <<<<<<<<<<<<<<
@@ -38817,7 +38987,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":3768
+  /* "pywrapfst.pyx":3780
  *   fst.Push(deref(ifst._fst), tfst.get(), flags, fst.GetReweightType(to_final),
  *            delta)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38825,13 +38995,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, 3768, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3780, __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":3717
+  /* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38931,7 +39101,7 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3717, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3729, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38954,15 +39124,15 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3718, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3730, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__42;
     }
     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, 3719, __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, 3731, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3719
+      /* "pywrapfst.pyx":3731
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -38972,10 +39142,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3720, __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, 3732, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3720
+      /* "pywrapfst.pyx":3732
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -38985,10 +39155,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3721, __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, 3733, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3721
+      /* "pywrapfst.pyx":3733
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -38998,10 +39168,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3722, __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, 3734, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3722
+      /* "pywrapfst.pyx":3734
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -39011,10 +39181,10 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3723, __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, 3735, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3723
+      /* "pywrapfst.pyx":3735
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -39026,16 +39196,16 @@ static PyObject *__pyx_pw_9pywrapfst_43push(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, 3717, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3729, __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, 3717, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3729, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_42push(__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":3717
+  /* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39066,7 +39236,7 @@ static PyObject *__pyx_pf_9pywrapfst_42push(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, 3717, __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, 3729, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39083,7 +39253,7 @@ static PyObject *__pyx_pf_9pywrapfst_42push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3771
+/* "pywrapfst.pyx":3783
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39124,18 +39294,18 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
     }
   }
 
-  /* "pywrapfst.pyx":3806
+  /* "pywrapfst.pyx":3818
  *   See also: `equal`, `equivalent`, `isomorphic`, `randgen`.
  *   """
  *   cdef fst.RandArcSelection ras = _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, 3806, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3806, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3818, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3818, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3809
+  /* "pywrapfst.pyx":3821
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
  *   # The three trailing options will be ignored by RandEquivalent.
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,             # <<<<<<<<<<<<<<
@@ -39144,7 +39314,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, 1, 0, 0));
 
-  /* "pywrapfst.pyx":3811
+  /* "pywrapfst.pyx":3823
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
  *                                                           1, False, False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39154,7 +39324,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":3812
+    /* "pywrapfst.pyx":3824
  *                                                           1, False, False))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -39163,7 +39333,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3811
+    /* "pywrapfst.pyx":3823
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
  *                                                           1, False, False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39172,7 +39342,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   }
 
-  /* "pywrapfst.pyx":3813
+  /* "pywrapfst.pyx":3825
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,             # <<<<<<<<<<<<<<
@@ -39181,14 +39351,14 @@ 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, 3813, __pyx_L1_error)
+    __PYX_ERR(0, 3825, __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, 3813, __pyx_L1_error)
+    __PYX_ERR(0, 3825, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3814
+  /* "pywrapfst.pyx":3826
  *     seed = time(NULL) + getpid()
  *   return fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst), npath, delta,
  *                            seed, deref(opts))             # <<<<<<<<<<<<<<
@@ -39198,7 +39368,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_delta, __pyx_v_seed, (*__pyx_v_opts));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3771
+  /* "pywrapfst.pyx":3783
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39263,7 +39433,7 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(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, 3771, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3783, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39297,7 +39467,7 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(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, 3771, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3783, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39320,37 +39490,37 @@ static PyObject *__pyx_pw_9pywrapfst_45randequivalent(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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3773, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3785, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((__pyx_t_10basictypes_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, 3774, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3786, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__43;
     }
     if (values[4]) {
-      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[4]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3775, __pyx_L3_error)
+      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[4]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3787, __pyx_L3_error)
     } else {
       __pyx_v_seed = ((time_t)0);
     }
     __pyx_v_select = values[5];
     if (values[6]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[6]); if (unlikely((__pyx_v_max_length == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3777, __pyx_L3_error)
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[6]); if (unlikely((__pyx_v_max_length == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3789, __pyx_L3_error)
     } else {
       __pyx_v_max_length = __pyx_k__44;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3771, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3783, __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, 3771, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3772, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3783, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3784, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_44randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length);
 
   /* function exit code */
@@ -39376,8 +39546,8 @@ static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__
   __pyx_t_2.seed = __pyx_v_seed;
   __pyx_t_2.select = __pyx_v_select;
   __pyx_t_2.max_length = __pyx_v_max_length;
-  __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, 3771, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3771, __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, 3783, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3783, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39394,7 +39564,7 @@ static PyObject *__pyx_pf_9pywrapfst_44randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3817
+/* "pywrapfst.pyx":3829
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39409,7 +39579,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
   PyObject *__pyx_v_select = ((PyObject *)__pyx_n_b_uniform);
   __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__45;
 
-  /* "pywrapfst.pyx":3822
+  /* "pywrapfst.pyx":3834
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39418,7 +39588,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3823
+  /* "pywrapfst.pyx":3835
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39457,18 +39627,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
     }
   }
 
-  /* "pywrapfst.pyx":3855
+  /* "pywrapfst.pyx":3867
  *   See also: `randequivalent`.
  *   """
  *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3855, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3855, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3867, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3867, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3857
+  /* "pywrapfst.pyx":3869
  *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))
  *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,             # <<<<<<<<<<<<<<
@@ -39477,7 +39647,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, __pyx_v_npath, __pyx_v_weighted, __pyx_v_remove_total_weight));
 
-  /* "pywrapfst.pyx":3861
+  /* "pywrapfst.pyx":3873
  *                                                           remove_total_weight))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -39486,11 +39656,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3861, __pyx_L1_error)
+    __PYX_ERR(0, 3873, __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":3862
+  /* "pywrapfst.pyx":3874
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39500,7 +39670,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3863
+    /* "pywrapfst.pyx":3875
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -39509,7 +39679,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3862
+    /* "pywrapfst.pyx":3874
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39518,7 +39688,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   }
 
-  /* "pywrapfst.pyx":3864
+  /* "pywrapfst.pyx":3876
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))             # <<<<<<<<<<<<<<
@@ -39527,11 +39697,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3864, __pyx_L1_error)
+    __PYX_ERR(0, 3876, __pyx_L1_error)
   }
   fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_seed, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3865
+  /* "pywrapfst.pyx":3877
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -39539,13 +39709,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  * 
  */
   __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, 3865, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3877, __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":3817
+  /* "pywrapfst.pyx":3829
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39646,7 +39816,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(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, 3817, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3829, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39669,26 +39839,26 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3818, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3830, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
     }
     if (values[2]) {
-      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[2]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3819, __pyx_L3_error)
+      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[2]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3831, __pyx_L3_error)
     } else {
       __pyx_v_seed = ((time_t)0);
     }
     __pyx_v_select = values[3];
     if (values[4]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[4]); if (unlikely((__pyx_v_max_length == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3821, __pyx_L3_error)
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[4]); if (unlikely((__pyx_v_max_length == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3833, __pyx_L3_error)
     } else {
       __pyx_v_max_length = __pyx_k__45;
     }
     if (values[5]) {
-      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3822, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3834, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3822
+      /* "pywrapfst.pyx":3834
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39698,10 +39868,10 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
       __pyx_v_weighted = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3823, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3835, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3823
+      /* "pywrapfst.pyx":3835
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39713,16 +39883,16 @@ static PyObject *__pyx_pw_9pywrapfst_47randgen(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3817, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3829, __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, 3817, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3829, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_46randgen(__pyx_self, __pyx_v_ifst, __pyx_v_npath, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length, __pyx_v_weighted, __pyx_v_remove_total_weight);
 
-  /* "pywrapfst.pyx":3817
+  /* "pywrapfst.pyx":3829
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39753,7 +39923,7 @@ static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.max_length = __pyx_v_max_length;
   __pyx_t_2.remove_total_weight = __pyx_v_weighted;
   __pyx_t_2.weighted = __pyx_v_remove_total_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3817, __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, 3829, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39770,7 +39940,7 @@ static PyObject *__pyx_pf_9pywrapfst_46randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3868
+/* "pywrapfst.pyx":3880
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -39783,7 +39953,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   PyObject *__pyx_v_call_arc_labeling = ((PyObject *)__pyx_n_b_input);
   PyObject *__pyx_v_return_arc_labeling = ((PyObject *)__pyx_n_b_neither);
 
-  /* "pywrapfst.pyx":3871
+  /* "pywrapfst.pyx":3883
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -39831,26 +40001,26 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     }
   }
 
-  /* "pywrapfst.pyx":3913
+  /* "pywrapfst.pyx":3925
  *   cdef int64 label
  *   cdef _Fst ifst
  *   it = iter(pairs)             # <<<<<<<<<<<<<<
  *   (root_label, ifst) = next(it)
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  */
-  __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3913, __pyx_L1_error)
+  __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3925, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_it = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3914
+  /* "pywrapfst.pyx":3926
  *   cdef _Fst ifst
  *   it = iter(pairs)
  *   (root_label, ifst) = next(it)             # <<<<<<<<<<<<<<
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  */
-  __pyx_t_1 = __Pyx_PyIter_Next(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3914, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyIter_Next(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3926, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
     PyObject* sequence = __pyx_t_1;
@@ -39858,7 +40028,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     if (unlikely(size != 2)) {
       if (size > 2) __Pyx_RaiseTooManyValuesError(2);
       else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-      __PYX_ERR(0, 3914, __pyx_L1_error)
+      __PYX_ERR(0, 3926, __pyx_L1_error)
     }
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
     if (likely(PyTuple_CheckExact(sequence))) {
@@ -39871,15 +40041,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     __Pyx_INCREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_t_3);
     #else
-    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3914, __pyx_L1_error)
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3926, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3914, __pyx_L1_error)
+    __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3926, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     #endif
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   } else {
     Py_ssize_t index = -1;
-    __pyx_t_4 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3914, __pyx_L1_error)
+    __pyx_t_4 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3926, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __pyx_t_5 = Py_TYPE(__pyx_t_4)->tp_iternext;
@@ -39887,7 +40057,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     __Pyx_GOTREF(__pyx_t_2);
     index = 1; __pyx_t_3 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed;
     __Pyx_GOTREF(__pyx_t_3);
-    if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 3914, __pyx_L1_error)
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 3926, __pyx_L1_error)
     __pyx_t_5 = NULL;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     goto __pyx_L4_unpacking_done;
@@ -39895,17 +40065,17 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_5 = NULL;
     if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-    __PYX_ERR(0, 3914, __pyx_L1_error)
+    __PYX_ERR(0, 3926, __pyx_L1_error)
     __pyx_L4_unpacking_done:;
   }
-  __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3914, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3926, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3914, __pyx_L1_error)
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3926, __pyx_L1_error)
   __pyx_v_root_label = __pyx_t_6;
   __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":3915
+  /* "pywrapfst.pyx":3927
  *   it = iter(pairs)
  *   (root_label, ifst) = next(it)
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))             # <<<<<<<<<<<<<<
@@ -39914,22 +40084,22 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   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, 3927, __pyx_L1_error)
   }
   try {
     __pyx_t_7 = __pyx_t_3fst_LabelFstClassPair(__pyx_v_root_label, __pyx_v_ifst->_fst.get());
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3915, __pyx_L1_error)
+    __PYX_ERR(0, 3927, __pyx_L1_error)
   }
   try {
     __pyx_v__pairs.push_back(__pyx_t_7);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3915, __pyx_L1_error)
+    __PYX_ERR(0, 3927, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3917
+  /* "pywrapfst.pyx":3929
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -39938,11 +40108,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3917, __pyx_L1_error)
+    __PYX_ERR(0, 3929, __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":3918
+  /* "pywrapfst.pyx":3930
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
@@ -39953,26 +40123,26 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     __pyx_t_1 = __pyx_v_it; __Pyx_INCREF(__pyx_t_1); __pyx_t_8 = 0;
     __pyx_t_9 = NULL;
   } else {
-    __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3918, __pyx_L1_error)
+    __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3930, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3918, __pyx_L1_error)
+    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3930, __pyx_L1_error)
   }
   for (;;) {
     if (likely(!__pyx_t_9)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
         if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 3918, __pyx_L1_error)
+        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 3930, __pyx_L1_error)
         #else
-        __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3918, __pyx_L1_error)
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3930, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         #endif
       } else {
         if (__pyx_t_8 >= 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_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 3918, __pyx_L1_error)
+        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_3); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 3930, __pyx_L1_error)
         #else
-        __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3918, __pyx_L1_error)
+        __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3930, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         #endif
       }
@@ -39982,7 +40152,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 3918, __pyx_L1_error)
+          else __PYX_ERR(0, 3930, __pyx_L1_error)
         }
         break;
       }
@@ -39994,7 +40164,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        __PYX_ERR(0, 3918, __pyx_L1_error)
+        __PYX_ERR(0, 3930, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -40007,15 +40177,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __Pyx_INCREF(__pyx_t_2);
       __Pyx_INCREF(__pyx_t_4);
       #else
-      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3918, __pyx_L1_error)
+      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3930, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3918, __pyx_L1_error)
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3930, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       #endif
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else {
       Py_ssize_t index = -1;
-      __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 3918, __pyx_L1_error)
+      __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 3930, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_5 = Py_TYPE(__pyx_t_10)->tp_iternext;
@@ -40023,7 +40193,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __Pyx_GOTREF(__pyx_t_2);
       index = 1; __pyx_t_4 = __pyx_t_5(__pyx_t_10); if (unlikely(!__pyx_t_4)) goto __pyx_L7_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_10), 2) < 0) __PYX_ERR(0, 3918, __pyx_L1_error)
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_10), 2) < 0) __PYX_ERR(0, 3930, __pyx_L1_error)
       __pyx_t_5 = NULL;
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       goto __pyx_L8_unpacking_done;
@@ -40031,17 +40201,17 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __pyx_t_5 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      __PYX_ERR(0, 3918, __pyx_L1_error)
+      __PYX_ERR(0, 3930, __pyx_L1_error)
       __pyx_L8_unpacking_done:;
     }
-    __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3918, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3930, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3918, __pyx_L1_error)
+    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3930, __pyx_L1_error)
     __pyx_v_label = __pyx_t_6;
     __Pyx_DECREF_SET(__pyx_v_ifst, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_4));
     __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":3919
+    /* "pywrapfst.pyx":3931
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   for (label, ifst) in it:
  *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))             # <<<<<<<<<<<<<<
@@ -40050,22 +40220,22 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3919, __pyx_L1_error)
+      __PYX_ERR(0, 3931, __pyx_L1_error)
     }
     try {
       __pyx_t_7 = __pyx_t_3fst_LabelFstClassPair(__pyx_v_label, __pyx_v_ifst->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3919, __pyx_L1_error)
+      __PYX_ERR(0, 3931, __pyx_L1_error)
     }
     try {
       __pyx_v__pairs.push_back(__pyx_t_7);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3919, __pyx_L1_error)
+      __PYX_ERR(0, 3931, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3918
+    /* "pywrapfst.pyx":3930
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
@@ -40075,45 +40245,45 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3921
+  /* "pywrapfst.pyx":3933
  *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
  *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
  *       tostring(call_arc_labeling), epsilon_on_replace)             # <<<<<<<<<<<<<<
  *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
  *       tostring(return_arc_labeling), epsilon_on_replace)
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3921, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3933, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3920
+  /* "pywrapfst.pyx":3932
  *   for (label, ifst) in it:
  *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))
  *   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_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3920, __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, 3932, __pyx_L1_error)
   __pyx_v_cal = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3923
+  /* "pywrapfst.pyx":3935
  *       tostring(call_arc_labeling), epsilon_on_replace)
  *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
  *       tostring(return_arc_labeling), epsilon_on_replace)             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3923, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3935, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3922
+  /* "pywrapfst.pyx":3934
  *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
  *       tostring(call_arc_labeling), 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_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3922, __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, 3934, __pyx_L1_error)
   __pyx_v_ral = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3925
+  /* "pywrapfst.pyx":3937
  *       tostring(return_arc_labeling), epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))             # <<<<<<<<<<<<<<
@@ -40122,7 +40292,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   __pyx_v_opts.reset(new fst::script::ReplaceOptions(__pyx_v_root_label, __pyx_v_cal, __pyx_v_ral, __pyx_v_return_label));
 
-  /* "pywrapfst.pyx":3926
+  /* "pywrapfst.pyx":3938
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -40131,7 +40301,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   fst::script::Replace(__pyx_v__pairs, __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3927
+  /* "pywrapfst.pyx":3939
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -40139,13 +40309,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  * 
  */
   __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, 3927, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3939, __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":3868
+  /* "pywrapfst.pyx":3880
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -40235,7 +40405,7 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(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, 3868, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3880, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40256,10 +40426,10 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(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, 3871, __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, 3883, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3871
+      /* "pywrapfst.pyx":3883
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -40269,14 +40439,14 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3872, __pyx_L3_error)
+      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3884, __pyx_L3_error)
     } else {
       __pyx_v_return_label = ((__pyx_t_10basictypes_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, 3868, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3880, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -40284,7 +40454,7 @@ static PyObject *__pyx_pw_9pywrapfst_49replace(PyObject *__pyx_self, PyObject *_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_48replace(__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":3868
+  /* "pywrapfst.pyx":3880
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -40309,7 +40479,7 @@ static PyObject *__pyx_pf_9pywrapfst_48replace(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, 3868, __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, 3880, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40326,7 +40496,7 @@ static PyObject *__pyx_pf_9pywrapfst_48replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3930
+/* "pywrapfst.pyx":3942
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40348,7 +40518,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
     }
   }
 
-  /* "pywrapfst.pyx":3950
+  /* "pywrapfst.pyx":3962
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40357,11 +40527,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3950, __pyx_L1_error)
+    __PYX_ERR(0, 3962, __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":3951
+  /* "pywrapfst.pyx":3963
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)             # <<<<<<<<<<<<<<
@@ -40370,11 +40540,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3951, __pyx_L1_error)
+    __PYX_ERR(0, 3963, __pyx_L1_error)
   }
   fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":3952
+  /* "pywrapfst.pyx":3964
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -40382,13 +40552,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  * 
  */
   __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, 3952, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3964, __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":3930
+  /* "pywrapfst.pyx":3942
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40443,7 +40613,7 @@ static PyObject *__pyx_pw_9pywrapfst_51reverse(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, 3930, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 3942, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40456,20 +40626,20 @@ static PyObject *__pyx_pw_9pywrapfst_51reverse(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, 3930, __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, 3942, __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, 3930, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3942, __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, 3930, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3942, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_50reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
@@ -40490,7 +40660,7 @@ static PyObject *__pyx_pf_9pywrapfst_50reverse(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, 3930, __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, 3942, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40507,7 +40677,7 @@ static PyObject *__pyx_pf_9pywrapfst_50reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3958
+/* "pywrapfst.pyx":3970
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40520,7 +40690,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__47;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":3962
+  /* "pywrapfst.pyx":3974
  *                                                 int64 nstate=fst.kNoStateId,
  *                                                 queue_type=b"auto",
  *                                                 bool reverse=False) except *:             # <<<<<<<<<<<<<<
@@ -40552,7 +40722,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     }
   }
 
-  /* "pywrapfst.pyx":3964
+  /* "pywrapfst.pyx":3976
  *                                                 bool reverse=False) except *:
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -40563,11 +40733,11 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3964, __pyx_L1_error)
+    __PYX_ERR(0, 3976, __pyx_L1_error)
   }
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":3968
+  /* "pywrapfst.pyx":3980
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40577,7 +40747,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_t_2 = (__pyx_v_reverse != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3971
+    /* "pywrapfst.pyx":3983
  *     # Only the simpler signature supports shortest distance to final states;
  *     # `nstate` and `queue_type` arguments are ignored.
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)             # <<<<<<<<<<<<<<
@@ -40586,11 +40756,11 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3971, __pyx_L1_error)
+      __PYX_ERR(0, 3983, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":3968
+    /* "pywrapfst.pyx":3980
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40600,7 +40770,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":3973
+  /* "pywrapfst.pyx":3985
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -40609,17 +40779,17 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":3974
+    /* "pywrapfst.pyx":3986
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(
  *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,             # <<<<<<<<<<<<<<
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
  */
-    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3974, __pyx_L1_error)
-    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3974, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3986, __pyx_L1_error)
+    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3986, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3973
+    /* "pywrapfst.pyx":3985
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -40628,7 +40798,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     __pyx_v_opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_4, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
 
-    /* "pywrapfst.pyx":3976
+    /* "pywrapfst.pyx":3988
  *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -40637,13 +40807,13 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3976, __pyx_L1_error)
+      __PYX_ERR(0, 3988, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), (*__pyx_v_opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":3977
+  /* "pywrapfst.pyx":3989
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
  *   return distance.release()             # <<<<<<<<<<<<<<
@@ -40653,7 +40823,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_r = __pyx_v_distance.release();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3958
+  /* "pywrapfst.pyx":3970
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40670,7 +40840,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3980
+/* "pywrapfst.pyx":3992
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40743,7 +40913,7 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(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, 3980, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 3992, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40762,21 +40932,21 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(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, 3981, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3993, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__48;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3982, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3994, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__49;
     }
     __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, 3984, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3996, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3984
+      /* "pywrapfst.pyx":3996
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
@@ -40788,16 +40958,16 @@ static PyObject *__pyx_pw_9pywrapfst_53shortestdistance(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, 3980, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3992, __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, 3980, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3992, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_52shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":3992
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40830,7 +41000,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":4012
+  /* "pywrapfst.pyx":4024
  *   """
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))             # <<<<<<<<<<<<<<
@@ -40842,10 +41012,10 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.reverse = __pyx_v_reverse;
-  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4012, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4024, __pyx_L1_error)
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4013
+  /* "pywrapfst.pyx":4025
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
  *   cdef string weight_type = ifst.weight_type()             # <<<<<<<<<<<<<<
@@ -40854,11 +41024,11 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4013, __pyx_L1_error)
+    __PYX_ERR(0, 4025, __pyx_L1_error)
   }
   __pyx_v_weight_type = ((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0);
 
-  /* "pywrapfst.pyx":4014
+  /* "pywrapfst.pyx":4026
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
  *   cdef string weight_type = ifst.weight_type()
  *   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]             # <<<<<<<<<<<<<<
@@ -40867,7 +41037,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
  */
   __Pyx_XDECREF(__pyx_r);
   { /* enter inner scope */
-    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4014, __pyx_L1_error)
+    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4026, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_1 = &(*__pyx_v_distance);
     __pyx_t_4 = __pyx_t_1->begin();
@@ -40876,11 +41046,11 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
       __pyx_t_5 = *__pyx_t_4;
       ++__pyx_t_4;
       __pyx_7genexpr__pyx_v_weight = __pyx_t_5;
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4014, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4026, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4014, __pyx_L1_error)
+      __pyx_t_7 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4026, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4014, __pyx_L1_error)
+      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4026, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
@@ -40888,10 +41058,10 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
       PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_7);
       __pyx_t_6 = 0;
       __pyx_t_7 = 0;
-      __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4014, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4026, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4014, __pyx_L1_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4026, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
   } /* exit inner scope */
@@ -40899,7 +41069,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":3992
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40921,7 +41091,7 @@ static PyObject *__pyx_pf_9pywrapfst_52shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4017
+/* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40936,7 +41106,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
   __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__51;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":4022
+  /* "pywrapfst.pyx":4034
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -40945,7 +41115,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4023
+  /* "pywrapfst.pyx":4035
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -40984,7 +41154,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
     }
   }
 
-  /* "pywrapfst.pyx":4055
+  /* "pywrapfst.pyx":4067
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40993,11 +41163,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4055, __pyx_L1_error)
+    __PYX_ERR(0, 4067, __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":4057
+  /* "pywrapfst.pyx":4069
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -41006,22 +41176,22 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4057, __pyx_L1_error)
+    __PYX_ERR(0, 4069, __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, 4057, __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, 4069, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4059
+  /* "pywrapfst.pyx":4071
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   cdef unique_ptr[fst.ShortestPathOptions] opts
  *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
  *                                          nshortest, unique, delta, wc, nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4059, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4059, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4060
+  /* "pywrapfst.pyx":4072
  *   cdef unique_ptr[fst.ShortestPathOptions] opts
  *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
  *                                          nshortest, unique, delta, wc, nstate))             # <<<<<<<<<<<<<<
@@ -41030,7 +41200,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   __pyx_v_opts.reset(new fst::script::ShortestPathOptions(__pyx_t_3, __pyx_v_nshortest, __pyx_v_unique, __pyx_v_delta, __pyx_v_wc, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":4061
+  /* "pywrapfst.pyx":4073
  *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
  *                                          nshortest, unique, delta, wc, nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -41039,11 +41209,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4061, __pyx_L1_error)
+    __PYX_ERR(0, 4073, __pyx_L1_error)
   }
   fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":4062
+  /* "pywrapfst.pyx":4074
  *                                          nshortest, unique, delta, wc, nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -41051,13 +41221,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  * 
  */
   __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, 4062, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4074, __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":4017
+  /* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41095,7 +41265,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(PyObject *__pyx_self, PyObje
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":4023
+    /* "pywrapfst.pyx":4035
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -41167,7 +41337,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(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, 4017, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4029, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41190,26 +41360,26 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(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, 4018, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4030, __pyx_L3_error)
     } else {
       __pyx_v_delta = __pyx_k__50;
     }
     if (values[2]) {
-      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4019, __pyx_L3_error)
+      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4031, __pyx_L3_error)
     } else {
       __pyx_v_nshortest = ((__pyx_t_10basictypes_int32)1);
     }
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4020, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4032, __pyx_L3_error)
     } else {
       __pyx_v_nstate = __pyx_k__51;
     }
     __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, 4022, __pyx_L3_error)
+      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4034, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4022
+      /* "pywrapfst.pyx":4034
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -41222,16 +41392,16 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestpath(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, 4017, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4029, __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, 4017, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4029, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_54shortestpath(__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":4017
+  /* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41262,7 +41432,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestpath(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, 4017, __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, 4029, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41279,7 +41449,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4065
+/* "pywrapfst.pyx":4077
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41295,7 +41465,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
   struct __pyx_opt_args_9pywrapfst__map __pyx_t_2;
   __Pyx_RefNannySetupContext("statemap", 0);
 
-  /* "pywrapfst.pyx":4088
+  /* "pywrapfst.pyx":4102
  *   See also: `arcmap`.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, 1., None)             # <<<<<<<<<<<<<<
@@ -41308,13 +41478,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
   __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, 4088, __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, 4102, __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":4065
+  /* "pywrapfst.pyx":4077
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41335,7 +41505,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_56statemap[] = "\n  state_map(ifst, map_type)\n\n  Constructively applies a transform to all states.\n\n  This operation transforms each state according to the requested map type.\n  Note that currently, only one state-mapping operation is supported.\n\n  Args:\n    ifst: The input FST.\n    map_type: A string matching a known mapping operation; one of: \"arc_sum\"\n        (sum weights of identically-labeled multi-arcs), \"arc_unique\" (deletes\n        non-unique identically-labeled multi-arcs).\n\n  Returns:\n    An FST with states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n\n  See also: `arcmap`.\n  ";
+static char __pyx_doc_9pywrapfst_56statemap[] = "\n  state_map(ifst, map_type)\n\n  Constructively applies a transform to all states.\n\n  This operation transforms each state using one of the following:\n\n    * arc_sum: sums weights of identically-labeled multi-arcs.\n    * arc_unique: deletes non-unique identically-labeled multi-arcs.\n    * identity: maps to self.\n\n  Args:\n    ifst: The input FST.\n    map_type: A string matching a known mapping operation; one of: \"arc_sum\",\n        \"arc_unique\", \"identity\".\n\n  Returns:\n    An FST with states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n\n  See also: `arcmap`.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_57statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_map_type = 0;
@@ -41365,11 +41535,11 @@ static PyObject *__pyx_pw_9pywrapfst_57statemap(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, 4065, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4077, __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, 4065, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4077, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -41382,13 +41552,13 @@ static PyObject *__pyx_pw_9pywrapfst_57statemap(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, 4065, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4077, __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, 4065, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4077, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_56statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
@@ -41406,7 +41576,7 @@ static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_se
   PyObject *__pyx_t_1 = NULL;
   __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, 4065, __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, 4077, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41423,7 +41593,7 @@ static PyObject *__pyx_pf_9pywrapfst_56statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4091
+/* "pywrapfst.pyx":4105
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41439,7 +41609,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4111
+  /* "pywrapfst.pyx":4125
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -41448,11 +41618,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4111, __pyx_L1_error)
+    __PYX_ERR(0, 4125, __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":4112
+  /* "pywrapfst.pyx":4126
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())             # <<<<<<<<<<<<<<
@@ -41461,11 +41631,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4112, __pyx_L1_error)
+    __PYX_ERR(0, 4126, __pyx_L1_error)
   }
   fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get());
 
-  /* "pywrapfst.pyx":4113
+  /* "pywrapfst.pyx":4127
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -41473,13 +41643,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  * 
  */
   __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, 4113, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4127, __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":4091
+  /* "pywrapfst.pyx":4105
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41505,7 +41675,7 @@ static PyObject *__pyx_pw_9pywrapfst_59synchronize(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, 4091, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4105, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_58synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
 
   /* function exit code */
@@ -41523,7 +41693,7 @@ static PyObject *__pyx_pf_9pywrapfst_58synchronize(CYTHON_UNUSED PyObject *__pyx
   PyObject *__pyx_t_1 = NULL;
   __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, 4091, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4105, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41540,7 +41710,7 @@ static PyObject *__pyx_pf_9pywrapfst_58synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4170
+/* "pywrapfst.pyx":4184
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -41568,7 +41738,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_fst_type,&__pyx_n_s_arc_type,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_keep_isymbols,&__pyx_n_s_keep_osymbols,&__pyx_n_s_keep_state_numbering,&__pyx_n_s_allow_negative_labels,0};
     PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":4173
+    /* "pywrapfst.pyx":4187
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -41577,7 +41747,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":4174
+    /* "pywrapfst.pyx":4188
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -41586,7 +41756,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":4175
+    /* "pywrapfst.pyx":4189
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -41684,7 +41854,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, 4170, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4184, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41713,12 +41883,12 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       }
     }
     if (values[0]) {
-      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4171, __pyx_L3_error)
+      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4185, __pyx_L3_error)
     } else {
       __pyx_v_fst_type = __pyx_k__52;
     }
     if (values[1]) {
-      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4172, __pyx_L3_error)
+      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4186, __pyx_L3_error)
     } else {
       __pyx_v_arc_type = __pyx_k__53;
     }
@@ -41726,10 +41896,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, 4176, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4190, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4176
+      /* "pywrapfst.pyx":4190
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -41739,10 +41909,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, 4177, __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, 4191, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4177
+      /* "pywrapfst.pyx":4191
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -41752,10 +41922,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, 4178, __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, 4192, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4178
+      /* "pywrapfst.pyx":4192
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -41765,10 +41935,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, 4179, __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, 4193, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4179
+      /* "pywrapfst.pyx":4193
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -41778,10 +41948,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, 4180, __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, 4194, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4180
+      /* "pywrapfst.pyx":4194
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -41793,18 +41963,18 @@ 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, 4170, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4184, __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_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4173, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4174, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4175, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4187, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4188, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4189, __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":4170
+  /* "pywrapfst.pyx":4184
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -41831,7 +42001,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   fst::SymbolTable *__pyx_t_5;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4181
+  /* "pywrapfst.pyx":4195
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -41840,45 +42010,45 @@ 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, 4181, __pyx_L1_error)
+    __PYX_ERR(0, 4195, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4182
+  /* "pywrapfst.pyx":4196
  *                 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_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4182, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4196, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4182, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4196, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4182, __pyx_L1_error)
+    __PYX_ERR(0, 4196, __pyx_L1_error)
   }
   __pyx_v_self->_fst_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4183
+  /* "pywrapfst.pyx":4197
  *     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_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4183, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4197, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4183, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4197, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4183, __pyx_L1_error)
+    __PYX_ERR(0, 4197, __pyx_L1_error)
   }
   __pyx_v_self->_arc_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4184
+  /* "pywrapfst.pyx":4198
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
@@ -41887,11 +42057,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, 4184, __pyx_L1_error)
+    __PYX_ERR(0, 4198, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4185
+  /* "pywrapfst.pyx":4199
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -41902,7 +42072,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_4 = (__pyx_t_3 != 0);
   if (__pyx_t_4) {
 
-    /* "pywrapfst.pyx":4186
+    /* "pywrapfst.pyx":4200
  *     self._isymbols = NULL
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table             # <<<<<<<<<<<<<<
@@ -41911,16 +42081,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'", "_table");
-      __PYX_ERR(0, 4186, __pyx_L1_error)
+      __PYX_ERR(0, 4200, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_isymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-      __PYX_ERR(0, 4186, __pyx_L1_error)
+      __PYX_ERR(0, 4200, __pyx_L1_error)
     }
     __pyx_v_self->_isymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4185
+    /* "pywrapfst.pyx":4199
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -41929,7 +42099,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4187
+  /* "pywrapfst.pyx":4201
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
@@ -41938,11 +42108,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, 4187, __pyx_L1_error)
+    __PYX_ERR(0, 4201, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4188
+  /* "pywrapfst.pyx":4202
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -41953,7 +42123,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_3 = (__pyx_t_4 != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4189
+    /* "pywrapfst.pyx":4203
  *     self._osymbols = NULL
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table             # <<<<<<<<<<<<<<
@@ -41962,16 +42132,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'", "_table");
-      __PYX_ERR(0, 4189, __pyx_L1_error)
+      __PYX_ERR(0, 4203, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_osymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-      __PYX_ERR(0, 4189, __pyx_L1_error)
+      __PYX_ERR(0, 4203, __pyx_L1_error)
     }
     __pyx_v_self->_osymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4188
+    /* "pywrapfst.pyx":4202
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -41980,7 +42150,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4190
+  /* "pywrapfst.pyx":4204
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -41989,11 +42159,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, 4190, __pyx_L1_error)
+    __PYX_ERR(0, 4204, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4191
+  /* "pywrapfst.pyx":4205
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42004,7 +42174,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   __pyx_t_4 = (__pyx_t_3 != 0);
   if (__pyx_t_4) {
 
-    /* "pywrapfst.pyx":4192
+    /* "pywrapfst.pyx":4206
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
@@ -42013,16 +42183,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'", "_table");
-      __PYX_ERR(0, 4192, __pyx_L1_error)
+      __PYX_ERR(0, 4206, __pyx_L1_error)
     }
     __pyx_t_5 = __pyx_v_ssymbols->__pyx_base.__pyx_base._table;
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-      __PYX_ERR(0, 4192, __pyx_L1_error)
+      __PYX_ERR(0, 4206, __pyx_L1_error)
     }
     __pyx_v_self->_ssymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4191
+    /* "pywrapfst.pyx":4205
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42031,7 +42201,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4193
+  /* "pywrapfst.pyx":4207
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
@@ -42040,11 +42210,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, 4193, __pyx_L1_error)
+    __PYX_ERR(0, 4207, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4194
+  /* "pywrapfst.pyx":4208
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
@@ -42053,11 +42223,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, 4194, __pyx_L1_error)
+    __PYX_ERR(0, 4208, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4195
+  /* "pywrapfst.pyx":4209
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -42066,11 +42236,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, 4195, __pyx_L1_error)
+    __PYX_ERR(0, 4209, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4196
+  /* "pywrapfst.pyx":4210
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -42079,11 +42249,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, 4196, __pyx_L1_error)
+    __PYX_ERR(0, 4210, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4197
+  /* "pywrapfst.pyx":4211
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
@@ -42092,11 +42262,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, 4197, __pyx_L1_error)
+    __PYX_ERR(0, 4211, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4170
+  /* "pywrapfst.pyx":4184
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42116,7 +42286,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4199
+/* "pywrapfst.pyx":4213
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42144,7 +42314,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(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_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4199, __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, 4213, __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));
@@ -42161,10 +42331,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(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, 4199, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4213, __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, 4199, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4213, __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;
@@ -42183,7 +42353,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     #endif
   }
 
-  /* "pywrapfst.pyx":4214
+  /* "pywrapfst.pyx":4228
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -42192,10 +42362,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4214, __pyx_L1_error)
+    __PYX_ERR(0, 4228, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4215
+  /* "pywrapfst.pyx":4229
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
  *         b"<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,             # <<<<<<<<<<<<<<
@@ -42204,18 +42374,18 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4215, __pyx_L1_error)
+    __PYX_ERR(0, 4229, __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, 4215, __pyx_L1_error)
+    __PYX_ERR(0, 4229, __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, 4215, __pyx_L1_error)
+    __PYX_ERR(0, 4229, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4216
+  /* "pywrapfst.pyx":4230
  *     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,             # <<<<<<<<<<<<<<
@@ -42224,22 +42394,22 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4216, __pyx_L1_error)
+    __PYX_ERR(0, 4230, __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, 4216, __pyx_L1_error)
+    __PYX_ERR(0, 4230, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4216, __pyx_L1_error)
+    __PYX_ERR(0, 4230, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4216, __pyx_L1_error)
+    __PYX_ERR(0, 4230, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4217
+  /* "pywrapfst.pyx":4231
  *         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,             # <<<<<<<<<<<<<<
@@ -42248,14 +42418,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4217, __pyx_L1_error)
+    __PYX_ERR(0, 4231, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4217, __pyx_L1_error)
+    __PYX_ERR(0, 4231, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4218
+  /* "pywrapfst.pyx":4232
  *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
  *         self._keep_osymbols, self._keep_state_numbering,
  *         self._allow_negative_labels))             # <<<<<<<<<<<<<<
@@ -42264,10 +42434,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4218, __pyx_L1_error)
+    __PYX_ERR(0, 4232, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4214
+  /* "pywrapfst.pyx":4228
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -42276,7 +42446,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   __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));
 
-  /* "pywrapfst.pyx":4219
+  /* "pywrapfst.pyx":4233
  *         self._keep_osymbols, self._keep_state_numbering,
  *         self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -42285,11 +42455,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4219, __pyx_L1_error)
+    __PYX_ERR(0, 4233, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4220
+  /* "pywrapfst.pyx":4234
  *         self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -42299,14 +42469,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
   __pyx_t_5 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4221
+    /* "pywrapfst.pyx":4235
  *     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, 4221, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4235, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -42320,14 +42490,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     }
     __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, 4221, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4235, __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, 4221, __pyx_L1_error)
+    __PYX_ERR(0, 4235, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4220
+    /* "pywrapfst.pyx":4234
  *         self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -42336,7 +42506,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   }
 
-  /* "pywrapfst.pyx":4222
+  /* "pywrapfst.pyx":4236
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  *     return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -42344,13 +42514,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  *   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, 4222, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4236, __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":4199
+  /* "pywrapfst.pyx":4213
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42392,7 +42562,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4199, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4213, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42409,7 +42579,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4224
+/* "pywrapfst.pyx":4238
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42438,7 +42608,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, 4224, __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, 4238, __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);
@@ -42454,7 +42624,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, 4224, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4238, __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;
@@ -42474,17 +42644,17 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     #endif
   }
 
-  /* "pywrapfst.pyx":4240
+  /* "pywrapfst.pyx":4254
  *       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, 4240, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4254, __pyx_L1_error)
   __pyx_v_line = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4241
+  /* "pywrapfst.pyx":4255
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -42502,7 +42672,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4242
+    /* "pywrapfst.pyx":4256
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')             # <<<<<<<<<<<<<<
@@ -42511,7 +42681,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
     (void)(__pyx_v_line.append(((char const *)"\n")));
 
-    /* "pywrapfst.pyx":4241
+    /* "pywrapfst.pyx":4255
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -42520,7 +42690,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   }
 
-  /* "pywrapfst.pyx":4243
+  /* "pywrapfst.pyx":4257
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')
  *     deref(self._sstrm) << line             # <<<<<<<<<<<<<<
@@ -42529,11 +42699,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, 4243, __pyx_L1_error)
+    __PYX_ERR(0, 4257, __pyx_L1_error)
   }
   (void)(((*__pyx_v_self->_sstrm) << __pyx_v_line));
 
-  /* "pywrapfst.pyx":4224
+  /* "pywrapfst.pyx":4238
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42573,7 +42743,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __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, 4224, __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, 4238, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42697,7 +42867,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4265
+/* "pywrapfst.pyx":4279
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42732,28 +42902,28 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4266
+  /* "pywrapfst.pyx":4280
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4266, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4280, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4267
+  /* "pywrapfst.pyx":4281
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4267, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4267, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4267, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -42769,7 +42939,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4267, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -42785,14 +42955,14 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4266, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4280, __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, 4266, __pyx_L1_error)
+  __PYX_ERR(0, 4280, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4265
+  /* "pywrapfst.pyx":4279
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42814,7 +42984,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4269
+/* "pywrapfst.pyx":4283
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -42847,7 +43017,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4270
+  /* "pywrapfst.pyx":4284
  * 
  *   def __repr__(self):
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -42855,15 +43025,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4270, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4284, __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'", "far_type");
-    __PYX_ERR(0, 4270, __pyx_L1_error)
+    __PYX_ERR(0, 4284, __pyx_L1_error)
   }
-  __pyx_t_3 = __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_3)) __PYX_ERR(0, 4270, __pyx_L1_error)
+  __pyx_t_3 = __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_3)) __PYX_ERR(0, 4284, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4270, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4284, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -42880,7 +43050,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4270, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -42890,7 +43060,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4270, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -42898,7 +43068,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4270, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4284, __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;
@@ -42909,7 +43079,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4270, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4284, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -42918,7 +43088,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4269
+  /* "pywrapfst.pyx":4283
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -42942,7 +43112,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4273
+/* "pywrapfst.pyx":4287
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
@@ -42986,7 +43156,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("open", 0);
 
-  /* "pywrapfst.pyx":4292
+  /* "pywrapfst.pyx":4306
  *     """
  *     cdef vector[string] filename_strings
  *     for filename in filenames:             # <<<<<<<<<<<<<<
@@ -42997,30 +43167,30 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   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, 4292, __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, 4306, __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, 4292, __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, 4306, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     #endif
     __Pyx_XDECREF_SET(__pyx_v_filename, __pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":4293
+    /* "pywrapfst.pyx":4307
  *     cdef vector[string] filename_strings
  *     for filename in filenames:
  *       filename_strings.push_back(tostring(filename))             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
  */
-    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4293, __pyx_L1_error)
+    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4307, __pyx_L1_error)
     try {
       __pyx_v_filename_strings.push_back(__pyx_t_4);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4293, __pyx_L1_error)
+      __PYX_ERR(0, 4307, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":4292
+    /* "pywrapfst.pyx":4306
  *     """
  *     cdef vector[string] filename_strings
  *     for filename in filenames:             # <<<<<<<<<<<<<<
@@ -43030,7 +43200,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4295
+  /* "pywrapfst.pyx":4309
  *       filename_strings.push_back(tostring(filename))
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(filename_strings))             # <<<<<<<<<<<<<<
@@ -43039,7 +43209,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   __pyx_v_tfar.reset(fst::script::FarReaderClass::Open(__pyx_v_filename_strings));
 
-  /* "pywrapfst.pyx":4296
+  /* "pywrapfst.pyx":4310
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
@@ -43049,16 +43219,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_t_5 = ((__pyx_v_tfar.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4297
+    /* "pywrapfst.pyx":4311
  *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
  *     if tfar.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filenames))             # <<<<<<<<<<<<<<
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4297, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4311, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4297, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4311, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -43072,7 +43242,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     }
     __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_filenames) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filenames);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4297, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4311, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -43088,14 +43258,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     __pyx_t_1 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __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_1)) __PYX_ERR(0, 4297, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4311, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4297, __pyx_L1_error)
+    __PYX_ERR(0, 4311, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4296
+    /* "pywrapfst.pyx":4310
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(filename_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
@@ -43104,19 +43274,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   }
 
-  /* "pywrapfst.pyx":4298
+  /* "pywrapfst.pyx":4312
  *     if tfar.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filenames))
  *     cdef FarReader result = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
  *     result._reader.reset(tfar.release())
  *     return result
  */
-  __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, 4298, __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, 4312, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4299
+  /* "pywrapfst.pyx":4313
  *       raise FstIOError("Read failed: {!r}".format(filenames))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())             # <<<<<<<<<<<<<<
@@ -43125,11 +43295,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4299, __pyx_L1_error)
+    __PYX_ERR(0, 4313, __pyx_L1_error)
   }
   __pyx_v_result->_reader.reset(__pyx_v_tfar.release());
 
-  /* "pywrapfst.pyx":4300
+  /* "pywrapfst.pyx":4314
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())
  *     return result             # <<<<<<<<<<<<<<
@@ -43141,7 +43311,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4273
+  /* "pywrapfst.pyx":4287
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
@@ -43166,7 +43336,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4302
+/* "pywrapfst.pyx":4316
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -43193,7 +43363,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, 4302, __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, 4316, __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);
@@ -43209,10 +43379,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, 4302, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4316, __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, 4302, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4316, __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;
@@ -43231,7 +43401,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4308
+  /* "pywrapfst.pyx":4322
  *     Returns a string indicating the arc type.
  *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
@@ -43240,12 +43410,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, 4308, __pyx_L1_error)
+    __PYX_ERR(0, 4322, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4302
+  /* "pywrapfst.pyx":4316
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -43286,7 +43456,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4302, __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, 4316, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43303,7 +43473,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4310
+/* "pywrapfst.pyx":4324
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43330,7 +43500,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, 4310, __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, 4324, __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);
@@ -43346,10 +43516,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, 4310, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4324, __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, 4310, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4324, __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;
@@ -43368,7 +43538,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4319
+  /* "pywrapfst.pyx":4333
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -43377,12 +43547,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, 4319, __pyx_L1_error)
+    __PYX_ERR(0, 4333, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4310
+  /* "pywrapfst.pyx":4324
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43423,7 +43593,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __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, 4310, __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, 4324, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43440,7 +43610,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4321
+/* "pywrapfst.pyx":4335
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43467,7 +43637,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, 4321, __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, 4335, __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);
@@ -43483,10 +43653,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, 4321, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4335, __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, 4321, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4335, __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;
@@ -43505,7 +43675,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4330
+  /* "pywrapfst.pyx":4344
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -43514,12 +43684,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, 4330, __pyx_L1_error)
+    __PYX_ERR(0, 4344, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4321
+  /* "pywrapfst.pyx":4335
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43560,7 +43730,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4321, __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, 4335, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43577,7 +43747,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4332
+/* "pywrapfst.pyx":4346
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43604,7 +43774,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, 4332, __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, 4346, __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);
@@ -43620,10 +43790,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, 4332, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4346, __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, 4332, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4346, __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;
@@ -43642,7 +43812,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4333
+  /* "pywrapfst.pyx":4347
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
@@ -43651,12 +43821,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, 4333, __pyx_L1_error)
+    __PYX_ERR(0, 4347, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4332
+  /* "pywrapfst.pyx":4346
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43696,7 +43866,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 4332, __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, 4346, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43713,7 +43883,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4335
+/* "pywrapfst.pyx":4349
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
@@ -43741,7 +43911,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, 4335, __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, 4349, __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);
@@ -43757,10 +43927,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, 4335, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4349, __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, 4335, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4349, __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;
@@ -43779,7 +43949,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4348
+  /* "pywrapfst.pyx":4362
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
@@ -43788,13 +43958,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, 4348, __pyx_L1_error)
+    __PYX_ERR(0, 4362, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4348, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4362, __pyx_L1_error)
   __pyx_r = __pyx_v_self->_reader.get()->Find(__pyx_t_6);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4335
+  /* "pywrapfst.pyx":4349
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
@@ -43836,8 +44006,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4335, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4335, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4349, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4349, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -43854,7 +44024,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4350
+/* "pywrapfst.pyx":4364
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -43880,7 +44050,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     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, 4350, __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, 4364, __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));
@@ -43897,10 +44067,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
         }
         __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, 4350, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4364, __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, 4350, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4364, __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;
@@ -43919,7 +44089,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     #endif
   }
 
-  /* "pywrapfst.pyx":4359
+  /* "pywrapfst.pyx":4373
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
@@ -43928,7 +44098,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":4360
+  /* "pywrapfst.pyx":4374
  *     """
  *     return _init_XFst(new fst.FstClass(
  *         deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
@@ -43937,23 +44107,23 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4360, __pyx_L1_error)
+    __PYX_ERR(0, 4374, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4359
+  /* "pywrapfst.pyx":4373
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
  *         deref(self._reader.get().GetFstClass())))
  * 
  */
-  __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, 4359, __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, 4373, __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":4350
+  /* "pywrapfst.pyx":4364
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -43995,7 +44165,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4350, __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, 4364, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44012,7 +44182,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4362
+/* "pywrapfst.pyx":4376
  *         deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44039,7 +44209,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, 4362, __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, 4376, __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);
@@ -44055,10 +44225,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, 4362, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4376, __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, 4362, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4376, __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;
@@ -44077,7 +44247,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":4371
+  /* "pywrapfst.pyx":4385
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -44086,12 +44256,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, 4371, __pyx_L1_error)
+    __PYX_ERR(0, 4385, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4362
+  /* "pywrapfst.pyx":4376
  *         deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44132,7 +44302,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4362, __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, 4376, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44149,7 +44319,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4373
+/* "pywrapfst.pyx":4387
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44174,7 +44344,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, 4373, __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, 4387, __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);
@@ -44190,7 +44360,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, 4373, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4387, __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;
@@ -44210,7 +44380,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4379
+  /* "pywrapfst.pyx":4393
  *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
@@ -44219,11 +44389,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, 4379, __pyx_L1_error)
+    __PYX_ERR(0, 4393, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4373
+  /* "pywrapfst.pyx":4387
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44263,7 +44433,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_1 = NULL;
   __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, 4373, __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, 4387, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44280,7 +44450,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4381
+/* "pywrapfst.pyx":4395
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44305,7 +44475,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, 4381, __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, 4395, __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);
@@ -44321,7 +44491,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, 4381, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4395, __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;
@@ -44341,7 +44511,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4387
+  /* "pywrapfst.pyx":4401
  *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
@@ -44350,11 +44520,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, 4387, __pyx_L1_error)
+    __PYX_ERR(0, 4401, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4381
+  /* "pywrapfst.pyx":4395
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44394,7 +44564,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4381, __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, 4395, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44411,7 +44581,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4389
+/* "pywrapfst.pyx":4403
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44440,7 +44610,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4390
+  /* "pywrapfst.pyx":4404
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -44449,13 +44619,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, 4390, __pyx_L1_error)
+    __PYX_ERR(0, 4404, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4390, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4404, __pyx_L1_error)
   __pyx_t_2 = (__pyx_v_self->_reader.get()->Find(__pyx_t_1) != 0);
   if (likely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":4391
+    /* "pywrapfst.pyx":4405
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):
  *       return self.get_fst()             # <<<<<<<<<<<<<<
@@ -44465,15 +44635,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, 4391, __pyx_L1_error)
+      __PYX_ERR(0, 4405, __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, 4391, __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, 4405, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_r = __pyx_t_3;
     __pyx_t_3 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":4390
+    /* "pywrapfst.pyx":4404
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -44482,7 +44652,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4393
+  /* "pywrapfst.pyx":4407
  *       return self.get_fst()
  *     else:
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
@@ -44490,14 +44660,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  * 
  */
   /*else*/ {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4393, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4407, __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, 4393, __pyx_L1_error)
+    __PYX_ERR(0, 4407, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4389
+  /* "pywrapfst.pyx":4403
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44623,7 +44793,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4416
+/* "pywrapfst.pyx":4430
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44658,28 +44828,28 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4417
+  /* "pywrapfst.pyx":4431
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4417, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4431, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4418
+  /* "pywrapfst.pyx":4432
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4418, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4418, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4418, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -44695,7 +44865,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4418, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -44711,14 +44881,14 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4417, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4431, __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, 4417, __pyx_L1_error)
+  __PYX_ERR(0, 4431, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4416
+  /* "pywrapfst.pyx":4430
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44740,7 +44910,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4420
+/* "pywrapfst.pyx":4434
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44773,7 +44943,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4421
+  /* "pywrapfst.pyx":4435
  * 
  *   def __repr__(self):
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -44781,15 +44951,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4421, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4435, __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'", "far_type");
-    __PYX_ERR(0, 4421, __pyx_L1_error)
+    __PYX_ERR(0, 4435, __pyx_L1_error)
   }
-  __pyx_t_3 = __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_3)) __PYX_ERR(0, 4421, __pyx_L1_error)
+  __pyx_t_3 = __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_3)) __PYX_ERR(0, 4435, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4421, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4435, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -44806,7 +44976,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4421, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44816,7 +44986,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4421, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44824,7 +44994,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4421, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4435, __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;
@@ -44835,7 +45005,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4421, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4435, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -44844,7 +45014,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4420
+  /* "pywrapfst.pyx":4434
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44868,7 +45038,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4424
+/* "pywrapfst.pyx":4438
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -44923,7 +45093,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, 4424, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4438, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -44942,7 +45112,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, 4424, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4438, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -44971,27 +45141,27 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4445
+  /* "pywrapfst.pyx":4459
  *       FstIOError: Read failed.
  *     """
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))             # <<<<<<<<<<<<<<
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4445, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4459, __pyx_L1_error)
   __pyx_v_ft = fst::script::GetFarType(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4447
+  /* "pywrapfst.pyx":4461
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)             # <<<<<<<<<<<<<<
  *     if tfar == NULL:
  *       raise FstIOError("Open failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4447, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4447, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4461, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4461, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4446
+  /* "pywrapfst.pyx":4460
  *     """
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
@@ -45000,7 +45170,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   __pyx_v_tfar = fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_v_ft);
 
-  /* "pywrapfst.pyx":4448
+  /* "pywrapfst.pyx":4462
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -45010,16 +45180,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_t_3 = ((__pyx_v_tfar == NULL) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":4449
+    /* "pywrapfst.pyx":4463
  *         tostring(filename), tostring(arc_type), ft)
  *     if tfar == NULL:
  *       raise FstIOError("Open failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4449, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4463, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4449, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4463, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -45033,7 +45203,7 @@ 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_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filename);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4449, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4463, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -45049,14 +45219,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     __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, 4449, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4463, __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, 4449, __pyx_L1_error)
+    __PYX_ERR(0, 4463, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4448
+    /* "pywrapfst.pyx":4462
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -45065,19 +45235,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   }
 
-  /* "pywrapfst.pyx":4450
+  /* "pywrapfst.pyx":4464
  *     if tfar == NULL:
  *       raise FstIOError("Open failed: {!r}".format(filename))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)             # <<<<<<<<<<<<<<
  *     result._writer.reset(tfar)
  *     return result
  */
-  __pyx_t_4 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4450, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_4));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_4);
   __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":4451
+  /* "pywrapfst.pyx":4465
  *       raise FstIOError("Open failed: {!r}".format(filename))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)             # <<<<<<<<<<<<<<
@@ -45086,11 +45256,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4451, __pyx_L1_error)
+    __PYX_ERR(0, 4465, __pyx_L1_error)
   }
   __pyx_v_result->_writer.reset(__pyx_v_tfar);
 
-  /* "pywrapfst.pyx":4452
+  /* "pywrapfst.pyx":4466
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  *     return result             # <<<<<<<<<<<<<<
@@ -45102,7 +45272,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4424
+  /* "pywrapfst.pyx":4438
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -45126,7 +45296,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4456
+/* "pywrapfst.pyx":4470
  *   # 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):             # <<<<<<<<<<<<<<
@@ -45138,7 +45308,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("close", 0);
 
-  /* "pywrapfst.pyx":4457
+  /* "pywrapfst.pyx":4471
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
@@ -45147,11 +45317,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, 4457, __pyx_L1_error)
+    __PYX_ERR(0, 4471, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4456
+  /* "pywrapfst.pyx":4470
  *   # 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):             # <<<<<<<<<<<<<<
@@ -45167,7 +45337,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4459
+/* "pywrapfst.pyx":4473
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45196,7 +45366,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, 4459, __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, 4473, __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);
@@ -45215,7 +45385,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, 4459, __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, 4473, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -45223,13 +45393,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, 4459, __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, 4473, __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, 4459, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4473, __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;
@@ -45240,7 +45410,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, 4459, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4473, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -45262,7 +45432,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     #endif
   }
 
-  /* "pywrapfst.pyx":4478
+  /* "pywrapfst.pyx":4492
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45271,24 +45441,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, 4478, __pyx_L1_error)
+    __PYX_ERR(0, 4492, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4478, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4492, __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, 4478, __pyx_L1_error)
+    __PYX_ERR(0, 4492, __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":4479
+    /* "pywrapfst.pyx":4493
  *     # 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")             # <<<<<<<<<<<<<<
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4479, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4493, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -45302,14 +45472,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, 4479, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4493, __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, 4479, __pyx_L1_error)
+    __PYX_ERR(0, 4493, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4478
+    /* "pywrapfst.pyx":4492
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45318,7 +45488,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4481
+  /* "pywrapfst.pyx":4495
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45327,19 +45497,19 @@ 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, 4481, __pyx_L1_error)
+    __PYX_ERR(0, 4495, __pyx_L1_error)
   }
   __pyx_t_8 = (__pyx_v_self->_writer.get()->Error() != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "pywrapfst.pyx":4482
+    /* "pywrapfst.pyx":4496
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():
  *       raise FstArgError("Key out of order")             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4482, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4496, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -45353,14 +45523,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_Key_out_of_order) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Key_out_of_order);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4482, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4496, __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, 4482, __pyx_L1_error)
+    __PYX_ERR(0, 4496, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4481
+    /* "pywrapfst.pyx":4495
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45369,7 +45539,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4459
+  /* "pywrapfst.pyx":4473
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45422,11 +45592,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, 4459, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4473, __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, 4459, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4473, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -45439,13 +45609,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, 4459, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4473, __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, 4459, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4473, __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 */
@@ -45463,8 +45633,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_1 = NULL;
   __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, 4459, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4459, __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, 4473, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4473, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45481,7 +45651,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4484
+/* "pywrapfst.pyx":4498
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -45508,7 +45678,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, 4484, __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, 4498, __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);
@@ -45524,10 +45694,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, 4484, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4498, __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, 4484, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4498, __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;
@@ -45546,7 +45716,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4490
+  /* "pywrapfst.pyx":4504
  *     Returns a string indicating the arc type.
  *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
@@ -45555,12 +45725,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, 4490, __pyx_L1_error)
+    __PYX_ERR(0, 4504, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4484
+  /* "pywrapfst.pyx":4498
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -45601,7 +45771,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4484, __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, 4498, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45618,7 +45788,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4492
+/* "pywrapfst.pyx":4506
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45645,7 +45815,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, 4492, __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, 4506, __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);
@@ -45661,10 +45831,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, 4492, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4506, __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, 4492, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4506, __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;
@@ -45683,7 +45853,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     #endif
   }
 
-  /* "pywrapfst.pyx":4501
+  /* "pywrapfst.pyx":4515
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -45692,12 +45862,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, 4501, __pyx_L1_error)
+    __PYX_ERR(0, 4515, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4492
+  /* "pywrapfst.pyx":4506
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45738,7 +45908,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4492, __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, 4506, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45755,7 +45925,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4503
+/* "pywrapfst.pyx":4517
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45782,7 +45952,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, 4503, __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, 4517, __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);
@@ -45798,10 +45968,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, 4503, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4517, __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, 4503, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4517, __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;
@@ -45820,7 +45990,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4509
+  /* "pywrapfst.pyx":4523
  *     Returns a string indicating the FAR type.
  *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
@@ -45829,12 +45999,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, 4509, __pyx_L1_error)
+    __PYX_ERR(0, 4523, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4503
+  /* "pywrapfst.pyx":4517
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45875,7 +46045,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 4503, __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, 4517, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45892,7 +46062,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4512
+/* "pywrapfst.pyx":4526
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -45906,7 +46076,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, 4512, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst__Fst, 1, "fst", 0))) __PYX_ERR(0, 4526, __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 */
@@ -45923,7 +46093,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4513
+  /* "pywrapfst.pyx":4527
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
@@ -45932,11 +46102,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, 4513, __pyx_L1_error)
+    __PYX_ERR(0, 4527, __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, 4513, __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, 4527, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4512
+  /* "pywrapfst.pyx":4526
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -46640,6 +46810,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Weight = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_vtable_9pywrapfst__SymbolTable;
 
@@ -46752,6 +46925,9 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable __pyx_vtable_9pywrapfst__EncodeMapperSymbolTable;
 
@@ -46844,6 +47020,9 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable __pyx_vtable_9pywrapfst__FstSymbolTable;
 
@@ -46936,6 +47115,9 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable __pyx_vtable_9pywrapfst__MutableSymbolTable;
 
@@ -47019,6 +47201,9 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable __pyx_vtable_9pywrapfst__MutableFstSymbolTable;
 
@@ -47111,6 +47296,9 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable __pyx_vtable_9pywrapfst_SymbolTable;
 
@@ -47202,6 +47390,9 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTable = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator __pyx_vtable_9pywrapfst_SymbolTableIterator;
 
@@ -47303,6 +47494,9 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper __pyx_vtable_9pywrapfst_EncodeMapper;
 
@@ -47402,6 +47596,9 @@ static PyTypeObject __pyx_type_9pywrapfst_EncodeMapper = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__Fst __pyx_vtable_9pywrapfst__Fst;
 
@@ -47512,6 +47709,9 @@ static PyTypeObject __pyx_type_9pywrapfst__Fst = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableFst __pyx_vtable_9pywrapfst__MutableFst;
 
@@ -47539,36 +47739,37 @@ static void __pyx_tp_dealloc_9pywrapfst__MutableFst(PyObject *o) {
 static PyMethodDef __pyx_methods_9pywrapfst__MutableFst[] = {
   {"add_arc", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_1add_arc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_add_arc},
   {"add_state", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_3add_state, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_2add_state},
-  {"arcsort", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_5arcsort, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_4arcsort},
-  {"closure", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_7closure, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_6closure},
-  {"concat", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_9concat, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_8concat},
-  {"connect", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_11connect, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_10connect},
-  {"decode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_13decode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_12decode},
-  {"delete_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_15delete_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_14delete_arcs},
-  {"delete_states", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_17delete_states, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_16delete_states},
-  {"encode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_19encode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_18encode},
-  {"invert", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_21invert, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_20invert},
-  {"minimize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_23minimize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_22minimize},
-  {"mutable_arcs", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_25mutable_arcs, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_24mutable_arcs},
-  {"mutable_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_27mutable_input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_26mutable_input_symbols},
-  {"mutable_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_29mutable_output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_28mutable_output_symbols},
-  {"num_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_31num_states, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_30num_states},
-  {"project", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_33project, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_32project},
-  {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_35prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_34prune},
-  {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_37push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_36push},
-  {"relabel_pairs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_39relabel_pairs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_38relabel_pairs},
-  {"relabel_tables", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_40relabel_tables},
-  {"reserve_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_42reserve_arcs},
-  {"reserve_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_45reserve_states, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_44reserve_states},
-  {"reweight", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_47reweight, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_46reweight},
-  {"rmepsilon", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_48rmepsilon},
-  {"set_final", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_51set_final, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_50set_final},
-  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_53set_input_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_52set_input_symbols},
-  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_55set_output_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_54set_output_symbols},
-  {"set_properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_57set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_56set_properties},
-  {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_59set_start, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_58set_start},
-  {"topsort", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_61topsort, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_60topsort},
-  {"union", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_63union, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_62union},
+  {"add_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_5add_states, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_4add_states},
+  {"arcsort", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_7arcsort, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_6arcsort},
+  {"closure", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_9closure, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_8closure},
+  {"concat", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_11concat, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_10concat},
+  {"connect", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_13connect, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_12connect},
+  {"decode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_15decode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_14decode},
+  {"delete_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs},
+  {"delete_states", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_19delete_states, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_18delete_states},
+  {"encode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_21encode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_20encode},
+  {"invert", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_23invert, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_22invert},
+  {"minimize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_25minimize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_24minimize},
+  {"mutable_arcs", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_26mutable_arcs},
+  {"mutable_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_28mutable_input_symbols},
+  {"mutable_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_30mutable_output_symbols},
+  {"num_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_33num_states, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_32num_states},
+  {"project", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_35project, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_34project},
+  {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_37prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_36prune},
+  {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_39push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_38push},
+  {"relabel_pairs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs},
+  {"relabel_tables", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_42relabel_tables},
+  {"reserve_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs},
+  {"reserve_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_46reserve_states},
+  {"reweight", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_49reweight, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_48reweight},
+  {"rmepsilon", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_50rmepsilon},
+  {"set_final", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_53set_final, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_52set_final},
+  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_54set_input_symbols},
+  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_56set_output_symbols},
+  {"set_properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_59set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_58set_properties},
+  {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_61set_start, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_60set_start},
+  {"topsort", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_63topsort, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_62topsort},
+  {"union", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_65union, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_64union},
   {0, 0, 0, 0}
 };
 
@@ -47640,6 +47841,9 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_Arc __pyx_vtable_9pywrapfst_Arc;
 
@@ -47796,6 +48000,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Arc = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator __pyx_vtable_9pywrapfst_ArcIterator;
 
@@ -47900,6 +48107,9 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator __pyx_vtable_9pywrapfst_MutableArcIterator;
 
@@ -48002,6 +48212,9 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator __pyx_vtable_9pywrapfst_StateIterator;
 
@@ -48102,6 +48315,9 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_Compiler __pyx_vtable_9pywrapfst_Compiler;
 
@@ -48203,6 +48419,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Compiler = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_FarReader __pyx_vtable_9pywrapfst_FarReader;
 
@@ -48330,6 +48549,9 @@ static PyTypeObject __pyx_type_9pywrapfst_FarReader = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_FarWriter __pyx_vtable_9pywrapfst_FarWriter;
 
@@ -48443,6 +48665,9 @@ static PyTypeObject __pyx_type_9pywrapfst_FarWriter = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 
 static struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *__pyx_freelist_9pywrapfst___pyx_scope_struct____iter__[8];
@@ -48538,6 +48763,9 @@ static PyTypeObject __pyx_type_9pywrapfst___pyx_scope_struct____iter__ = {
   #if PY_VERSION_HEX >= 0x030400a1
   0, /*tp_finalize*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
 };
 
 static PyMethodDef __pyx_methods[] = {
@@ -48772,6 +49000,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_acceptor, __pyx_k_acceptor, sizeof(__pyx_k_acceptor), 0, 0, 1, 1},
   {&__pyx_n_s_add, __pyx_k_add, sizeof(__pyx_k_add), 0, 0, 1, 1},
   {&__pyx_n_s_add_state, __pyx_k_add_state, sizeof(__pyx_k_add_state), 0, 0, 1, 1},
+  {&__pyx_n_s_add_states, __pyx_k_add_states, sizeof(__pyx_k_add_states), 0, 0, 1, 1},
   {&__pyx_n_s_add_symbol, __pyx_k_add_symbol, sizeof(__pyx_k_add_symbol), 0, 0, 1, 1},
   {&__pyx_n_s_add_table, __pyx_k_add_table, sizeof(__pyx_k_add_table), 0, 0, 1, 1},
   {&__pyx_n_s_allow_negative_labels, __pyx_k_allow_negative_labels, sizeof(__pyx_k_allow_negative_labels), 0, 0, 1, 1},
@@ -48996,12 +49225,12 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
   __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 122, __pyx_L1_error)
   __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 127, __pyx_L1_error)
   __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 132, __pyx_L1_error)
-  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2766, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 2786, __pyx_L1_error)
+  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2778, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 2798, __pyx_L1_error)
   __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 356, __pyx_L1_error)
   __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error)
   __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1170, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4393, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4407, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -49263,67 +49492,67 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GIVEREF(__pyx_tuple__66);
   __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 542, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 542, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2766
+  /* "pywrapfst.pyx":2778
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 2766, __pyx_L1_error)
+  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 2778, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__68);
   __Pyx_GIVEREF(__pyx_tuple__68);
 
-  /* "pywrapfst.pyx":2783
+  /* "pywrapfst.pyx":2795
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 2783, __pyx_L1_error)
+  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 2795, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__69);
   __Pyx_GIVEREF(__pyx_tuple__69);
-  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 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_new, 2783, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 2783, __pyx_L1_error)
-  __pyx_tuple__71 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 2783, __pyx_L1_error)
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 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_new, 2795, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 2795, __pyx_L1_error)
+  __pyx_tuple__71 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 2795, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__71);
   __Pyx_GIVEREF(__pyx_tuple__71);
 
-  /* "pywrapfst.pyx":2787
+  /* "pywrapfst.pyx":2799
  * 
  *    @staticmethod
  *    def read(filename):             # <<<<<<<<<<<<<<
  *      """
  *      read(filename):
  */
-  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_filename); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2787, __pyx_L1_error)
+  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_filename); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2799, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__72);
   __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read, 2787, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2787, __pyx_L1_error)
+  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read, 2799, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2799, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2805
+  /* "pywrapfst.pyx":2817
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
  *      read_from_string(string, fst_type=None)
  */
-  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2805, __pyx_L1_error)
+  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2817, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__74);
   __Pyx_GIVEREF(__pyx_tuple__74);
-  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 2805, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 2805, __pyx_L1_error)
+  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 2817, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 2817, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":3992
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__76 = PyTuple_Pack(8, __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_type, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 3980, __pyx_L1_error)
+  __pyx_tuple__76 = PyTuple_Pack(8, __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_type, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 3992, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__76);
   __Pyx_GIVEREF(__pyx_tuple__76);
-  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 3980, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 3980, __pyx_L1_error)
+  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 3992, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 3992, __pyx_L1_error)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -49434,7 +49663,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __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, 334, __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;
   }
@@ -49455,7 +49686,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__SymbolTable.write_text = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write_text;
   __pyx_vtable_9pywrapfst__SymbolTable.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write_to_string;
   if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 664, __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;
   }
@@ -49466,7 +49699,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__EncodeMapperSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
   __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
   if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 852, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_print = 0;
+  #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
@@ -49477,7 +49712,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__FstSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
   __pyx_type_9pywrapfst__FstSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
   if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 872, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__FstSymbolTable.tp_print = 0;
+  #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__FstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
@@ -49491,7 +49728,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __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__SymbolTable;
   if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 891, __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;
   }
@@ -49502,7 +49741,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__MutableFstSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
   if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 943, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_print = 0;
+  #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
@@ -49513,7 +49754,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_SymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_type_9pywrapfst_SymbolTable.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
   if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 954, __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;
   }
@@ -49527,7 +49770,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_SymbolTableIterator.symbol = (std::string (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_symbol;
   __pyx_vtable_9pywrapfst_SymbolTableIterator.value = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_value;
   if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1149, __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;
   }
@@ -49545,7 +49790,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_EncodeMapper.set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols;
   __pyx_vtable_9pywrapfst_EncodeMapper.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_weight_type;
   if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1231, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
+  #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_EncodeMapper.tp_dictoffset && __pyx_type_9pywrapfst_EncodeMapper.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_EncodeMapper.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
@@ -49585,7 +49832,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__Fst.write = (void (*)(struct __pyx_obj_9pywrapfst__Fst *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_write;
   __pyx_vtable_9pywrapfst__Fst.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_write_to_string;
   if (PyType_Ready(&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1387, __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;
   }
@@ -49597,6 +49846,7 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__MutableFst._check_mutating_imethod = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod;
   __pyx_vtable_9pywrapfst__MutableFst._add_arc = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_obj_9pywrapfst_Arc *))__pyx_f_9pywrapfst_11_MutableFst__add_arc;
   __pyx_vtable_9pywrapfst__MutableFst.add_state = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_add_state;
+  __pyx_vtable_9pywrapfst__MutableFst.add_states = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_add_states;
   __pyx_vtable_9pywrapfst__MutableFst._arcsort = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__arcsort;
   __pyx_vtable_9pywrapfst__MutableFst._closure = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__closure;
   __pyx_vtable_9pywrapfst__MutableFst._concat = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *))__pyx_f_9pywrapfst_11_MutableFst__concat;
@@ -49627,7 +49877,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst__MutableFst._union = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *))__pyx_f_9pywrapfst_11_MutableFst__union;
   __pyx_type_9pywrapfst__MutableFst.tp_base = __pyx_ptype_9pywrapfst__Fst;
   if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1802, __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;
   }
@@ -49636,14 +49888,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_ptype_9pywrapfst__MutableFst = &__pyx_type_9pywrapfst__MutableFst;
   __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, 2920, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __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, 2920, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2920, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2920, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2932, __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;
@@ -49654,14 +49908,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __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 *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, 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, 2987, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __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, 2987, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2999, __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;
@@ -49673,40 +49929,46 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint32, __pyx_t_10basictypes_uint32, 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, 3098, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __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, 3098, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3098, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3098, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3110, __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 = (__pyx_t_10basictypes_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, 3218, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __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 (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3218, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3218, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3218, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3230, __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, 4119, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __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, 4119, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4119, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4119, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4133, __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;
@@ -49718,14 +49980,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, 4249, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __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, 4249, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4249, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4249, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4263, __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;
@@ -49733,17 +49997,21 @@ 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, 4396, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __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, 4396, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4396, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4396, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4410, __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, 3118, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3130, __pyx_L1_error)
+  #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_print = 0;
+  #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_dictoffset && __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
   }
@@ -49943,10 +50211,9 @@ if (!__Pyx_RefNanny) {
   __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error)
   Py_INCREF(__pyx_d);
   __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error)
-  __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error)
-  #if CYTHON_COMPILING_IN_PYPY
   Py_INCREF(__pyx_b);
-  #endif
+  __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error)
+  Py_INCREF(__pyx_cython_runtime);
   if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error);
   /*--- Initialize various global constants etc. ---*/
   if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -49965,9 +50232,9 @@ if (!__Pyx_RefNanny) {
   }
   #endif
   /*--- Builtin init code ---*/
-  if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error;
   /*--- Constants init code ---*/
-  if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error;
   /*--- Global type/function init code ---*/
   (void)__Pyx_modinit_global_init_code();
   (void)__Pyx_modinit_variable_export_code();
@@ -50417,7 +50684,7 @@ if (!__Pyx_RefNanny) {
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":2090
+  /* "pywrapfst.pyx":2102
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -50426,7 +50693,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__11 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2096
+  /* "pywrapfst.pyx":2108
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -50435,7 +50702,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__12 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2196
+  /* "pywrapfst.pyx":2208
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -50445,7 +50712,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__13 = fst::kDelta;
   __pyx_k__14 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2205
+  /* "pywrapfst.pyx":2217
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -50454,7 +50721,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__15 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2206
+  /* "pywrapfst.pyx":2218
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -50463,7 +50730,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__16 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2233
+  /* "pywrapfst.pyx":2245
  * 
  *   cdef void _push(self,
  *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -50472,7 +50739,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__17 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2241
+  /* "pywrapfst.pyx":2253
  * 
  *   def push(self,
  *            float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -50481,7 +50748,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__18 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2478
+  /* "pywrapfst.pyx":2490
  *                        bool connect=True,
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -50490,7 +50757,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__19 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2479
+  /* "pywrapfst.pyx":2491
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:             # <<<<<<<<<<<<<<
@@ -50499,7 +50766,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__20 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2492
+  /* "pywrapfst.pyx":2504
  *                 bool connect=True,
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -50508,7 +50775,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__21 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2493
+  /* "pywrapfst.pyx":2505
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
  *                 float delta=fst.kShortestDelta):             # <<<<<<<<<<<<<<
@@ -50517,944 +50784,944 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__22 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2766
+  /* "pywrapfst.pyx":2778
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_tuple__68); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2766, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_tuple__68); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2778, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_tuple__68, __pyx_n_s_Fst_2, __pyx_n_s_Fst_2, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2766, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_tuple__68, __pyx_n_s_Fst_2, __pyx_n_s_Fst_2, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2778, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":2783
+  /* "pywrapfst.pyx":2795
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst___new, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2783, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst___new, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2795, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__71);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_new, __pyx_t_3) < 0) __PYX_ERR(0, 2783, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_new, __pyx_t_3) < 0) __PYX_ERR(0, 2795, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2787
+  /* "pywrapfst.pyx":2799
  * 
  *    @staticmethod
  *    def read(filename):             # <<<<<<<<<<<<<<
  *      """
  *      read(filename):
  */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_3read, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2787, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_3read, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2799, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2786
+  /* "pywrapfst.pyx":2798
  *     return _create_Fst(arc_type)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
  *    def read(filename):
  *      """
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2786, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2787, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2799, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2805
+  /* "pywrapfst.pyx":2817
  * 
  *    @staticmethod
  *    def read_from_string(state):             # <<<<<<<<<<<<<<
  *      """
  *      read_from_string(string, fst_type=None)
  */
-  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_5read_from_string, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read_from_string, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2805, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_5read_from_string, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read_from_string, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2817, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
 
-  /* "pywrapfst.pyx":2804
+  /* "pywrapfst.pyx":2816
  *      return _read(filename)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
  *    def read_from_string(state):
  *      """
  */
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2804, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2816, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read_from_string, __pyx_t_3) < 0) __PYX_ERR(0, 2805, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read_from_string, __pyx_t_3) < 0) __PYX_ERR(0, 2817, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2766
+  /* "pywrapfst.pyx":2778
  * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst_2, __pyx_tuple__68, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2766, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst_2, __pyx_tuple__68, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2778, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst_2, __pyx_t_3) < 0) __PYX_ERR(0, 2766, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst_2, __pyx_t_3) < 0) __PYX_ERR(0, 2778, __pyx_L1_error)
   __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":2829
+  /* "pywrapfst.pyx":2841
  * 
  * 
  * NO_LABEL = fst.kNoLabel             # <<<<<<<<<<<<<<
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2829, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2841, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_1) < 0) __PYX_ERR(0, 2829, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_1) < 0) __PYX_ERR(0, 2841, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2830
+  /* "pywrapfst.pyx":2842
  * 
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId             # <<<<<<<<<<<<<<
  * NO_SYMBOL = fst.kNoSymbol
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2830, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2842, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_1) < 0) __PYX_ERR(0, 2830, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_1) < 0) __PYX_ERR(0, 2842, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2831
+  /* "pywrapfst.pyx":2843
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2831, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2843, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_1) < 0) __PYX_ERR(0, 2831, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_1) < 0) __PYX_ERR(0, 2843, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2837
+  /* "pywrapfst.pyx":2849
  * 
  * 
  * EXPANDED = fst.kExpanded             # <<<<<<<<<<<<<<
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2837, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2849, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2837, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2849, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2838
+  /* "pywrapfst.pyx":2850
  * 
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable             # <<<<<<<<<<<<<<
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2838, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2850, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2838, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2850, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2839
+  /* "pywrapfst.pyx":2851
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError             # <<<<<<<<<<<<<<
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2839, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2851, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2839, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2851, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2840
+  /* "pywrapfst.pyx":2852
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor             # <<<<<<<<<<<<<<
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2840, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2852, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2840, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2852, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2841
+  /* "pywrapfst.pyx":2853
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor             # <<<<<<<<<<<<<<
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2841, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2853, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2841, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2853, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2842
+  /* "pywrapfst.pyx":2854
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic             # <<<<<<<<<<<<<<
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2842, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2854, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2842, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2854, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2843
+  /* "pywrapfst.pyx":2855
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic             # <<<<<<<<<<<<<<
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2843, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2855, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2843, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2855, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2844
+  /* "pywrapfst.pyx":2856
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic             # <<<<<<<<<<<<<<
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2844, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2856, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2844, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2856, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2845
+  /* "pywrapfst.pyx":2857
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic             # <<<<<<<<<<<<<<
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2845, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2857, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2845, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2857, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2846
+  /* "pywrapfst.pyx":2858
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons             # <<<<<<<<<<<<<<
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2846, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2858, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2846, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2858, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2847
+  /* "pywrapfst.pyx":2859
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons             # <<<<<<<<<<<<<<
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2847, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2859, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2847, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2859, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2848
+  /* "pywrapfst.pyx":2860
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons             # <<<<<<<<<<<<<<
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2848, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2860, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2848, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2860, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2849
+  /* "pywrapfst.pyx":2861
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons             # <<<<<<<<<<<<<<
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2849, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2849, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2850
+  /* "pywrapfst.pyx":2862
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2850, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2862, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2850, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2862, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2851
+  /* "pywrapfst.pyx":2863
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2851, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2863, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2851, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2852
+  /* "pywrapfst.pyx":2864
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2852, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2864, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2852, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2864, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2853
+  /* "pywrapfst.pyx":2865
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2853, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2865, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2853, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2865, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2854
+  /* "pywrapfst.pyx":2866
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2854, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2866, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2854, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2866, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2855
+  /* "pywrapfst.pyx":2867
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2855, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2867, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2855, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2867, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2856
+  /* "pywrapfst.pyx":2868
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted             # <<<<<<<<<<<<<<
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2856, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2868, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2856, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2868, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2857
+  /* "pywrapfst.pyx":2869
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted             # <<<<<<<<<<<<<<
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2857, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2869, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2857, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2869, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2858
+  /* "pywrapfst.pyx":2870
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic             # <<<<<<<<<<<<<<
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2858, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2870, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2858, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2870, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2859
+  /* "pywrapfst.pyx":2871
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic             # <<<<<<<<<<<<<<
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2859, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2871, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2859, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2871, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2860
+  /* "pywrapfst.pyx":2872
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic             # <<<<<<<<<<<<<<
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2860, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2872, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2860, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2872, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2861
+  /* "pywrapfst.pyx":2873
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic             # <<<<<<<<<<<<<<
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2861, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2873, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2873, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2862
+  /* "pywrapfst.pyx":2874
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted             # <<<<<<<<<<<<<<
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2862, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2874, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2862, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2874, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2863
+  /* "pywrapfst.pyx":2875
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted             # <<<<<<<<<<<<<<
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2875, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2875, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2864
+  /* "pywrapfst.pyx":2876
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible             # <<<<<<<<<<<<<<
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2864, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2876, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2864, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2876, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2865
+  /* "pywrapfst.pyx":2877
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible             # <<<<<<<<<<<<<<
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2865, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2877, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2865, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2877, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2866
+  /* "pywrapfst.pyx":2878
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible             # <<<<<<<<<<<<<<
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2866, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2866, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2878, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2867
+  /* "pywrapfst.pyx":2879
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible             # <<<<<<<<<<<<<<
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2867, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2879, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2867, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2879, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2868
+  /* "pywrapfst.pyx":2880
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString             # <<<<<<<<<<<<<<
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2868, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2880, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2868, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2880, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2869
+  /* "pywrapfst.pyx":2881
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString             # <<<<<<<<<<<<<<
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2869, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2881, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2869, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2881, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2870
+  /* "pywrapfst.pyx":2882
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles             # <<<<<<<<<<<<<<
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2870, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2882, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2870, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2882, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2871
+  /* "pywrapfst.pyx":2883
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles             # <<<<<<<<<<<<<<
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2871, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2883, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2871, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2883, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2872
+  /* "pywrapfst.pyx":2884
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties             # <<<<<<<<<<<<<<
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2872, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2884, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2872, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2884, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2873
+  /* "pywrapfst.pyx":2885
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties             # <<<<<<<<<<<<<<
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2873, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2885, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2873, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2885, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2874
+  /* "pywrapfst.pyx":2886
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties             # <<<<<<<<<<<<<<
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2874, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2886, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2874, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2886, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2875
+  /* "pywrapfst.pyx":2887
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties             # <<<<<<<<<<<<<<
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2875, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2887, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2875, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2887, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2876
+  /* "pywrapfst.pyx":2888
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2876, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2888, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2876, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2888, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2877
+  /* "pywrapfst.pyx":2889
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2877, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2889, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2877, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2889, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2878
+  /* "pywrapfst.pyx":2890
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2890, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2878, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2890, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2879
+  /* "pywrapfst.pyx":2891
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2879, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2891, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2879, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2891, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2880
+  /* "pywrapfst.pyx":2892
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2880, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2892, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2880, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2892, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2881
+  /* "pywrapfst.pyx":2893
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2881, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2893, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2881, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2893, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2882
+  /* "pywrapfst.pyx":2894
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2882, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2894, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2882, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2894, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2883
+  /* "pywrapfst.pyx":2895
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2883, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2895, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2883, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2895, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2884
+  /* "pywrapfst.pyx":2896
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2884, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2896, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2884, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2896, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2885
+  /* "pywrapfst.pyx":2897
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2885, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2897, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2885, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2897, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2886
+  /* "pywrapfst.pyx":2898
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2886, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2898, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2886, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2898, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2887
+  /* "pywrapfst.pyx":2899
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2887, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2899, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2887, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2899, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2888
+  /* "pywrapfst.pyx":2900
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2888, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2900, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2888, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2900, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2889
+  /* "pywrapfst.pyx":2901
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2889, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2901, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2889, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2901, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2890
+  /* "pywrapfst.pyx":2902
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2890, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2902, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2890, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2902, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2891
+  /* "pywrapfst.pyx":2903
  * 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_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2891, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2903, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2891, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2903, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2892
+  /* "pywrapfst.pyx":2904
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties             # <<<<<<<<<<<<<<
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2892, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2904, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2892, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2904, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2893
+  /* "pywrapfst.pyx":2905
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties             # <<<<<<<<<<<<<<
  * FST_PROPERTIES = fst.kFstProperties
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2893, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2905, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2893, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2905, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2894
+  /* "pywrapfst.pyx":2906
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2894, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2906, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2894, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2906, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2900
+  /* "pywrapfst.pyx":2912
  * 
  * 
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue             # <<<<<<<<<<<<<<
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2900, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2912, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2900, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2912, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2901
+  /* "pywrapfst.pyx":2913
  * 
  * 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_1 = __Pyx_PyInt_From_uint32_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2901, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2913, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2901, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2913, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2902
+  /* "pywrapfst.pyx":2914
  * 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_1 = __Pyx_PyInt_From_uint32_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2902, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2914, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2902, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2914, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2903
+  /* "pywrapfst.pyx":2915
  * 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_1 = __Pyx_PyInt_From_uint32_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2903, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2903, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2904
+  /* "pywrapfst.pyx":2916
  * 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_1 = __Pyx_PyInt_From_uint32_t(fst::kArcNoCache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2904, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcNoCache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2916, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_1) < 0) __PYX_ERR(0, 2904, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_1) < 0) __PYX_ERR(0, 2916, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2905
+  /* "pywrapfst.pyx":2917
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags             # <<<<<<<<<<<<<<
  * ARC_FLAGS = fst.kArcFlags
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2905, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2905, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2917, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2906
+  /* "pywrapfst.pyx":2918
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  * ARC_FLAGS = fst.kArcFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2906, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kArcFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2918, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2906, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2918, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2912
+  /* "pywrapfst.pyx":2924
  * 
  * 
  * ENCODE_LABELS = fst.kEncodeLabels             # <<<<<<<<<<<<<<
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2912, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2924, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_1) < 0) __PYX_ERR(0, 2912, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_1) < 0) __PYX_ERR(0, 2924, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2913
+  /* "pywrapfst.pyx":2925
  * 
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights             # <<<<<<<<<<<<<<
  * ENCODE_FLAGS = fst.kEncodeFlags
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2913, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2925, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_1) < 0) __PYX_ERR(0, 2913, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_1) < 0) __PYX_ERR(0, 2925, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2914
+  /* "pywrapfst.pyx":2926
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2914, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2926, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2914, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 2926, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3286
+  /* "pywrapfst.pyx":3298
  * 
  * cdef _Fst _map(_Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51463,7 +51730,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__31 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3300
+  /* "pywrapfst.pyx":3312
  * 
  * cpdef _Fst arcmap(_Fst ifst,
  *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51472,7 +51739,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__32 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3299
+  /* "pywrapfst.pyx":3311
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -51481,7 +51748,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__32 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3413
+  /* "pywrapfst.pyx":3425
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51490,7 +51757,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__33 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3415
+  /* "pywrapfst.pyx":3427
  *                               float delta=fst.kShortestDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51499,7 +51766,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__34 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3413
+  /* "pywrapfst.pyx":3425
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51508,7 +51775,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__33 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3415
+  /* "pywrapfst.pyx":3427
  *                               float delta=fst.kShortestDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51517,7 +51784,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__34 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3507
+  /* "pywrapfst.pyx":3519
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51526,7 +51793,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__35 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3508
+  /* "pywrapfst.pyx":3520
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51535,7 +51802,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__36 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3507
+  /* "pywrapfst.pyx":3519
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51544,7 +51811,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__35 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3508
+  /* "pywrapfst.pyx":3520
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51553,7 +51820,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__36 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3578
+  /* "pywrapfst.pyx":3590
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -51563,7 +51830,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__37 = fst::kDelta;
   __pyx_k__37 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3601
+  /* "pywrapfst.pyx":3613
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -51573,7 +51840,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__38 = fst::kDelta;
   __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3658
+  /* "pywrapfst.pyx":3670
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -51583,7 +51850,7 @@ if (!__Pyx_RefNanny) {
   __pyx_k__39 = fst::kDelta;
   __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3685
+  /* "pywrapfst.pyx":3697
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51592,7 +51859,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3686
+  /* "pywrapfst.pyx":3698
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51601,7 +51868,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__41 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3685
+  /* "pywrapfst.pyx":3697
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51610,7 +51877,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3686
+  /* "pywrapfst.pyx":3698
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51619,7 +51886,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__41 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3718
+  /* "pywrapfst.pyx":3730
  * 
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51628,7 +51895,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3717
+  /* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -51637,7 +51904,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3774
+  /* "pywrapfst.pyx":3786
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51646,7 +51913,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3777
+  /* "pywrapfst.pyx":3789
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
@@ -51655,7 +51922,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__44 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3774
+  /* "pywrapfst.pyx":3786
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -51664,7 +51931,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3777
+  /* "pywrapfst.pyx":3789
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
@@ -51673,7 +51940,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__44 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3821
+  /* "pywrapfst.pyx":3833
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
@@ -51682,7 +51949,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3817
+  /* "pywrapfst.pyx":3829
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -51691,7 +51958,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3959
+  /* "pywrapfst.pyx":3971
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *                                                 float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51700,7 +51967,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__46 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3960
+  /* "pywrapfst.pyx":3972
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *                                                 float delta=fst.kShortestDelta,
  *                                                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51709,7 +51976,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__47 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3981
+  /* "pywrapfst.pyx":3993
  * 
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51718,7 +51985,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__48 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3982
+  /* "pywrapfst.pyx":3994
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51727,19 +51994,19 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__49 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3980
+  /* "pywrapfst.pyx":3992
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_53shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3980, __pyx_L1_error)
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_53shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3992, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 3980, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 3992, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4018
+  /* "pywrapfst.pyx":4030
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51748,7 +52015,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__50 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4020
+  /* "pywrapfst.pyx":4032
  *                                float delta=fst.kShortestDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51757,7 +52024,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__51 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4018
+  /* "pywrapfst.pyx":4030
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
@@ -51766,7 +52033,7 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__50 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4020
+  /* "pywrapfst.pyx":4032
  *                                float delta=fst.kShortestDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -51775,75 +52042,75 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_k__51 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4171
+  /* "pywrapfst.pyx":4185
  * 
  *   def __cinit__(self,
  *                 string fst_type=b"vector",             # <<<<<<<<<<<<<<
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4171, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4185, __pyx_L1_error)
   __pyx_k__52 = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4172
+  /* "pywrapfst.pyx":4186
  *   def __cinit__(self,
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",             # <<<<<<<<<<<<<<
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4172, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4186, __pyx_L1_error)
   __pyx_k__53 = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4273
+  /* "pywrapfst.pyx":4287
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
  *     """
  *     FarReader.open(*filenames)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4273, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4287, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4272
+  /* "pywrapfst.pyx":4286
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def open(cls, *filenames):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4272, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4286, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_2) < 0) __PYX_ERR(0, 4273, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_2) < 0) __PYX_ERR(0, 4287, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4424
+  /* "pywrapfst.pyx":4438
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4424, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4438, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4423
+  /* "pywrapfst.pyx":4437
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4423, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_1) < 0) __PYX_ERR(0, 4424, __pyx_L1_error)
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_1) < 0) __PYX_ERR(0, 4438, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4516
+  /* "pywrapfst.pyx":4530
  * 
  * # Masks fst_error_fatal in-module.
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -51996,7 +52263,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args
     return result;
 }
 #if 1 || PY_VERSION_HEX < 0x030600B1
-static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) {
+static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) {
     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
     PyObject *globals = PyFunction_GET_GLOBALS(func);
     PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
@@ -52067,12 +52334,12 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
     }
 #if PY_MAJOR_VERSION >= 3
     result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL,
-                               args, nargs,
+                               args, (int)nargs,
                                k, (int)nk,
                                d, (int)nd, kwdefs, closure);
 #else
     result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL,
-                               args, nargs,
+                               args, (int)nargs,
                                k, (int)nk,
                                d, (int)nd, closure);
 #endif
@@ -54192,6 +54459,9 @@ static PyTypeObject __pyx_CyFunctionType_type = {
 #if PY_VERSION_HEX >= 0x030400a1
     0,
 #endif
+#if PY_VERSION_HEX >= 0x030800b1
+    0,
+#endif
 };
 static int __pyx_CyFunction_init(void) {
     __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
@@ -57181,6 +57451,9 @@ static PyTypeObject __pyx_GeneratorType_type = {
 #elif PY_VERSION_HEX >= 0x030400a1
     0,
 #endif
+#if PY_VERSION_HEX >= 0x030800b1
+    0,
+#endif
 };
 static int __pyx_Generator_init(void) {
     __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
index 9cce412..8dc646e 100644 (file)
@@ -8,10 +8,10 @@ from libc.time cimport time_t
 from libcpp cimport bool
 from libcpp.memory cimport shared_ptr
 from libcpp.memory cimport unique_ptr
+from libcpp.string cimport string
 from libcpp.utility cimport pair
 from libcpp.vector cimport vector
 
-from libcpp.string cimport string
 from basictypes cimport int32
 from basictypes cimport int64
 from basictypes cimport uint32
@@ -277,6 +277,8 @@ cdef class _MutableFst(_Fst):
 
   cpdef int64 add_state(self) except *
 
+  cpdef void add_states(self, size_t) except *
+
   cdef void _arcsort(self, sort_type=?) except *
 
   cdef void _closure(self, bool closure_plus=?) except *
index 3d76714..7dd7492 100644 (file)
@@ -1878,6 +1878,18 @@ cdef class _MutableFst(_Fst):
     self._check_mutating_imethod()
     return result
 
+  cpdef void add_states(self, size_t n) except *:
+    """
+    add_states(self, n)
+
+    Adds n new states to the FST.
+
+    Args:
+      n: The number of states to add.
+    """
+    self._mfst.get().AddStates(n)
+    self._check_mutating_imethod()
+
   cdef void _arcsort(self, sort_type=b"ilabel") except *:
     cdef fst.ArcSortType sort_type_enum
     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
@@ -4085,14 +4097,16 @@ cpdef _Fst statemap(_Fst ifst, map_type):
 
   Constructively applies a transform to all states.
 
-  This operation transforms each state according to the requested map type.
-  Note that currently, only one state-mapping operation is supported.
+  This operation transforms each state using one of the following:
+
+    * arc_sum: sums weights of identically-labeled multi-arcs.
+    * arc_unique: deletes non-unique identically-labeled multi-arcs.
+    * identity: maps to self.
 
   Args:
     ifst: The input FST.
-    map_type: A string matching a known mapping operation; one of: "arc_sum"
-        (sum weights of identically-labeled multi-arcs), "arc_unique" (deletes
-        non-unique identically-labeled multi-arcs).
+    map_type: A string matching a known mapping operation; one of: "arc_sum",
+        "arc_unique", "identity".
 
   Returns:
     An FST with states remapped.
index c5c135f..29929b4 100644 (file)
@@ -16,7 +16,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 16:0:0 -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 libfstspecial_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 phi_fst_la_SOURCES = phi-fst.cc
index dc98482..23a718f 100644 (file)
@@ -389,7 +389,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 16:0:0 -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 17:0:0 -lm $(DL_LIBS)
 libfstspecial_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -module
index 4c10d41..3702a5e 100644 (file)
@@ -1,7 +1,7 @@
 if HAVE_COMPRESS
 compress_include_headers = fst/extensions/compress/compress.h \
-fst/extensions/compress/compress-script.h fst/extensions/compress/gzfile.h \
-fst/extensions/compress/elias.h fst/extensions/compress/randmod.h
+fst/extensions/compress/compressscript.h fst/extensions/compress/gzfile.h \
+fst/extensions/compress/elias.h
 endif
 
 if HAVE_FAR
@@ -104,18 +104,20 @@ 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/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/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/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 \
index f1da49b..c930c33 100644 (file)
@@ -130,16 +130,17 @@ 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/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/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 \
@@ -155,10 +156,9 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/union-weight.h fst/union.h fst/util.h fst/vector-fst.h \
        fst/verify.h fst/visit.h fst/weight.h \
        fst/extensions/compress/compress.h \
-       fst/extensions/compress/compress-script.h \
+       fst/extensions/compress/compressscript.h \
        fst/extensions/compress/gzfile.h \
        fst/extensions/compress/elias.h \
-       fst/extensions/compress/randmod.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 \
@@ -406,8 +406,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 @HAVE_COMPRESS_TRUE@compress_include_headers = fst/extensions/compress/compress.h \
-@HAVE_COMPRESS_TRUE@fst/extensions/compress/compress-script.h fst/extensions/compress/gzfile.h \
-@HAVE_COMPRESS_TRUE@fst/extensions/compress/elias.h fst/extensions/compress/randmod.h
+@HAVE_COMPRESS_TRUE@fst/extensions/compress/compressscript.h fst/extensions/compress/gzfile.h \
+@HAVE_COMPRESS_TRUE@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 \
@@ -497,18 +497,20 @@ 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/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/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/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 \
index 5ae1924..cd053d3 100644 (file)
@@ -411,7 +411,7 @@ class CacheLogAccumulatorData {
 
   void AddWeights(StateId s, std::vector<double> *weights) {
     if (cache_gc_ && cache_size_ >= cache_limit_) GC(false);
-    cache_.insert(std::make_pair(s, CacheState(weights, true)));
+    cache_.emplace(s, CacheState(weights, true));
     if (cache_gc_) cache_size_ += weights->capacity() * sizeof(double);
   }
 
index 4a95111..92399ca 100644 (file)
@@ -9,6 +9,7 @@
 #define FST_ADD_ON_H_
 
 #include <stddef.h>
+
 #include <memory>
 #include <string>
 #include <utility>
@@ -108,7 +109,7 @@ class AddOnImpl : public FstImpl<typename FST::Arc> {
 
   // We make a thread-safe copy of the FST by default since an FST
   // implementation is expected to not share mutable data between objects.
-  AddOnImpl(const FST &fst, const string &type,
+  AddOnImpl(const FST &fst, const std::string &type,
             std::shared_ptr<T> t = std::shared_ptr<T>())
       : fst_(fst, true), t_(std::move(t)) {
     SetType(type);
@@ -119,7 +120,7 @@ class AddOnImpl : public FstImpl<typename FST::Arc> {
 
   // Conversion from const Fst<Arc> & to F always copies the underlying
   // implementation.
-  AddOnImpl(const Fst<Arc> &fst, const string &type,
+  AddOnImpl(const Fst<Arc> &fst, const std::string &type,
             std::shared_ptr<T> t = std::shared_ptr<T>())
       : fst_(fst), t_(std::move(t)) {
     SetType(type);
@@ -220,7 +221,7 @@ class AddOnImpl : public FstImpl<typename FST::Arc> {
   void SetAddOn(std::shared_ptr<T> t) { t_ = t; }
 
  private:
-  explicit AddOnImpl(const string &type) : t_() {
+  explicit AddOnImpl(const std::string &type) : t_() {
     SetType(type);
     SetProperties(kExpanded);
   }
index 13fe918..da0a3f5 100644 (file)
@@ -1,9 +1,15 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Allocators for contiguous arrays of arcs.
+
 #ifndef FST_ARC_ARENA_H_
 #define FST_ARC_ARENA_H_
 
 #include <deque>
 #include <memory>
 #include <utility>
+
 #include <fst/fst.h>
 #include <fst/memory.h>
 #include <unordered_map>
index 9ceead7..0254725 100644 (file)
@@ -107,7 +107,7 @@ void ArcMap(MutableFst<A> *fst, C *mapper) {
   auto superfinal = kNoStateId;
   if (final_action == MAP_REQUIRE_SUPERFINAL) {
     superfinal = fst->AddState();
-    fst->SetFinal(superfinal, Weight::One());
+    fst->SetFinal(superfinal);
   }
   for (StateIterator<MutableFst<FromArc>> siter(*fst); !siter.Done();
        siter.Next()) {
@@ -137,7 +137,7 @@ void ArcMap(MutableFst<A> *fst, C *mapper) {
             // Add a superfinal state if not already done.
             if (superfinal == kNoStateId) {
               superfinal = fst->AddState();
-              fst->SetFinal(superfinal, Weight::One());
+              fst->SetFinal(superfinal);
             }
             final_arc.nextstate = superfinal;
             fst->AddArc(state, std::move(final_arc));
@@ -208,7 +208,7 @@ void ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C *mapper) {
   StateId superfinal = kNoStateId;
   if (final_action == MAP_REQUIRE_SUPERFINAL) {
     superfinal = ofst->AddState();
-    ofst->SetFinal(superfinal, B::Weight::One());
+    ofst->SetFinal(superfinal);
   }
   for (StateIterator<Fst<A>> siter(ifst); !siter.Done(); siter.Next()) {
     StateId s = siter.Value();
@@ -235,7 +235,7 @@ void ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C *mapper) {
           // Add a superfinal state if not already done.
           if (superfinal == kNoStateId) {
             superfinal = ofst->AddState();
-            ofst->SetFinal(superfinal, B::Weight::One());
+            ofst->SetFinal(superfinal);
           }
           final_arc.nextstate = superfinal;
           ofst->AddArc(s, std::move(final_arc));
@@ -362,7 +362,7 @@ class ArcMapFstImpl : public CacheImpl<B> {
         }
         case MAP_ALLOW_SUPERFINAL: {
           if (s == superfinal_) {
-            SetFinal(s, Weight::One());
+            SetFinal(s);
           } else {
             const auto final_arc =
                 (*mapper_)(A(0, 0, fst_->Final(FindIState(s)), kNoStateId));
@@ -721,7 +721,7 @@ class SuperFinalMapper {
   using Weight = typename FromArc::Weight;;
 
   // Arg allows setting super-final label.
-  explicit SuperFinalMapper(Label final_label = 0)
+  constexpr explicit SuperFinalMapper(Label final_label = 0)
       : final_label_(final_label) {}
 
   ToArc operator()(const FromArc &arc) const {
@@ -755,7 +755,7 @@ class SuperFinalMapper {
   }
 
  private:
-  Label final_label_;
+  const Label final_label_;
 };
 
 // Mapper that leaves labels and nextstate unchanged and constructs a new weight
@@ -961,9 +961,9 @@ class GallicToNewSymbolsMapper {
     fst_->DeleteStates();
     state_ = fst_->AddState();
     fst_->SetStart(state_);
-    fst_->SetFinal(state_, AW::One());
+    fst_->SetFinal(state_);
     if (osymbols_) {
-      string name = osymbols_->Name() + "_from_gallic";
+      std::string name = osymbols_->Name() + "_from_gallic";
       fst_->SetInputSymbols(new SymbolTable(name));
       isymbols_ = fst_->MutableInputSymbols();
       const int64 zero = 0;
@@ -984,7 +984,7 @@ class GallicToNewSymbolsMapper {
     if (w1.Size() == 0) {
       l = 0;
     } else {
-      auto insert_result = map_.insert(std::make_pair(w1, kNoLabel));
+      auto insert_result = map_.emplace(w1, kNoLabel);
       if (!insert_result.second) {
         l = insert_result.first->second;
       } else {
@@ -992,11 +992,11 @@ class GallicToNewSymbolsMapper {
         insert_result.first->second = l;
         StringWeightIterator<SW> iter1(w1);
         StateId n;
-        string s;
+        std::string s;
         for (size_t i = 0, p = state_; i < w1.Size();
              ++i, iter1.Next(), p = n) {
           n = i == w1.Size() - 1 ? state_ : fst_->AddState();
-          fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), AW::One(), n));
+          fst_->AddArc(p, ToArc(i ? 0 : l, iter1.Value(), n));
           if (isymbols_) {
             if (i) s = s + "_";
             s = s + osymbols_->Find(iter1.Value());
index 651b11d..b9e07f6 100644 (file)
@@ -45,9 +45,13 @@ struct ArcTpl {
         weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const auto *const type =
-        new string(Weight::Type() == "tropical" ? "standard" : Weight::Type());
+  // Arc with weight One.
+  ArcTpl(Label ilabel, Label olabel, StateId nextstate)
+      : ArcTpl(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const auto *const type = new std::string(
+        Weight::Type() == "tropical" ? "standard" : Weight::Type());
     return *type;
   }
 };
@@ -74,15 +78,19 @@ struct StringArc {
 
   StringArc() = default;
 
-  template <class W>
-  StringArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  StringArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const auto *const type = new string(
+  // Arc with weight One.
+  StringArc(Label ilabel, Label olabel, StateId nextstate)
+      : StringArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const auto *const type = new std::string(
         S == STRING_LEFT ? "left_standard_string"
                          : (S == STRING_RIGHT ? "right_standard_string"
                                               : "restricted_standard_string"));
@@ -106,19 +114,25 @@ struct GallicArc {
 
   GallicArc() = default;
 
-  template <class W>
-  GallicArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  GallicArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
+  // Arc with weight One.
+  GallicArc(Label ilabel, Label olabel, StateId nextstate)
+      : GallicArc(ilabel, olabel, Weight::One(), nextstate) {}
+
   explicit GallicArc(const Arc &arc)
-      : ilabel(arc.ilabel), olabel(arc.ilabel), weight(arc.olabel, arc.weight),
+      : ilabel(arc.ilabel),
+        olabel(arc.ilabel),
+        weight(arc.olabel, arc.weight),
         nextstate(arc.nextstate) {}
 
-  static const string &Type() {
-    static const auto *const type = new string(
+  static const std::string &Type() {
+    static const auto *const type = new std::string(
         (G == GALLIC_LEFT
              ? "left_gallic_"
              : (G == GALLIC_RIGHT
@@ -137,8 +151,7 @@ struct ReverseArc {
   using Arc = A;
   using Label = typename Arc::Label;
   using StateId = typename Arc::StateId;
-  using AWeight = typename Arc::Weight;
-  using Weight = typename AWeight::ReverseWeight;
+  using Weight = typename Arc::Weight::ReverseWeight;
 
   Label ilabel;
   Label olabel;
@@ -147,15 +160,19 @@ struct ReverseArc {
 
   ReverseArc() = default;
 
-  template <class W>
-  ReverseArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  ReverseArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const auto *const type = new string("reverse_" + Arc::Type());
+  // Arc with weight One.
+  ReverseArc(Label ilabel, Label olabel, StateId nextstate)
+      : ReverseArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const auto *const type = new std::string("reverse_" + Arc::Type());
     return *type;
   }
 };
@@ -174,15 +191,19 @@ struct LexicographicArc {
 
   LexicographicArc() = default;
 
-  template <class W>
-  LexicographicArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  LexicographicArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const string *const type = new string(Weight::Type());
+  // Arc with weight One.
+  LexicographicArc(Label ilabel, Label olabel, StateId nextstate)
+      : LexicographicArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(Weight::Type());
     return *type;
   }
 };
@@ -201,15 +222,19 @@ struct ProductArc {
 
   ProductArc() = default;
 
-  template <class W>
-  ProductArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  ProductArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const auto *const type = new string(Weight::Type());
+  // Arc with weight One.
+  ProductArc(Label ilabel, Label olabel, StateId nextstate)
+      : ProductArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const auto *const type = new std::string(Weight::Type());
     return *type;
   }
 };
@@ -231,16 +256,20 @@ struct PowerArc {
 
   PowerArc() = default;
 
-  template <class W>
-  PowerArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  PowerArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
+  // Arc with weight One.
+  PowerArc(Label ilabel, Label olabel, StateId nextstate)
+      : PowerArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
     static const auto *const type =
-        new string(Arc::Type() + "_^" + std::to_string(n));
+        new std::string(Arc::Type() + "_^" + std::to_string(n));
     return *type;
   }
 };
@@ -261,20 +290,24 @@ struct SparsePowerArc {
 
   SparsePowerArc() = default;
 
-  template <class W>
-  SparsePowerArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  SparsePowerArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
-    static const string *const type = [] {
-      string type = Arc::Type() + "_^n";
+  // Arc with weight One.
+  SparsePowerArc(Label ilabel, Label olabel, StateId nextstate)
+      : SparsePowerArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
+    static const std::string *const type = [] {
+      std::string type = Arc::Type() + "_^n";
       if (sizeof(K) != sizeof(uint32)) {
         type += "_" + std::to_string(CHAR_BIT * sizeof(K));
       }
-      return new string(type);
+      return new std::string(type);
     }();
     return *type;
   }
@@ -298,16 +331,20 @@ struct ExpectationArc {
 
   ExpectationArc() = default;
 
-  template <class W>
-  ExpectationArc(Label ilabel, Label olabel, W &&weight, StateId nextstate)
+  template <class T>
+  ExpectationArc(Label ilabel, Label olabel, T &&weight, StateId nextstate)
       : ilabel(ilabel),
         olabel(olabel),
-        weight(std::forward<W>(weight)),
+        weight(std::forward<T>(weight)),
         nextstate(nextstate) {}
 
-  static const string &Type() {
+  // Arc with weight One.
+  ExpectationArc(Label ilabel, Label olabel, StateId nextstate)
+      : ExpectationArc(ilabel, olabel, Weight::One(), nextstate) {}
+
+  static const std::string &Type() {
     static const auto *const type =
-        new string("expectation_" + Arc::Type() + "_" + X2::Type());
+        new std::string("expectation_" + Arc::Type() + "_" + X2::Type());
     return *type;
   }
 };
index b5ab50e..e1260b6 100644 (file)
@@ -171,8 +171,9 @@ class ILabelCompare {
  public:
   constexpr ILabelCompare() {}
 
-  constexpr bool operator()(const Arc &arc1, const Arc &arc2) const {
-    return arc1.ilabel < arc2.ilabel;
+  constexpr bool operator()(const Arc &lhs, const Arc &rhs) const {
+    return std::forward_as_tuple(lhs.ilabel, lhs.olabel) <
+           std::forward_as_tuple(rhs.ilabel, rhs.olabel);
   }
 
   constexpr uint64 Properties(uint64 props) const {
@@ -187,8 +188,9 @@ class OLabelCompare {
  public:
   constexpr OLabelCompare() {}
 
-  constexpr bool operator()(const Arc &arc1, const Arc &arc2) const {
-    return arc1.olabel < arc2.olabel;
+  constexpr bool operator()(const Arc &lhs, const Arc &rhs) const {
+    return std::forward_as_tuple(lhs.olabel, lhs.ilabel) <
+           std::forward_as_tuple(rhs.olabel, rhs.ilabel);
   }
 
   constexpr uint64 Properties(uint64 props) const {
index 9651cfe..fa76f26 100644 (file)
@@ -112,10 +112,11 @@ struct HashSet : public std::unordered_set<K, H, E, PoolAllocator<K>> {
 // current_entry_. The hash and key equality functions map to entries first. H
 // is the hash function and E is the equality function. If passed to the
 // constructor, ownership is given to this class.
-// TODO(rybach): remove support for (deprecated and unused) HS_DENSE, HS_SPARSE.
 template <class I, class T, class H, class E = std::equal_to<T>,
           HSType HS = HS_FLAT>
 class CompactHashBiTable {
+  static_assert(HS == HS_STL || HS == HS_FLAT, "Unsupported hash set type");
+
  public:
   friend class HashFunc;
   friend class HashEqual;
@@ -182,11 +183,9 @@ class CompactHashBiTable {
  private:
   static_assert(std::is_signed<I>::value, "I must be a signed type");
   // ... otherwise >= kCurrentKey comparisons as used below don't work.
-  // TODO(rybach): (1) remove kEmptyKey, kDeletedKey, (2) don't use >= for key
-  // comparison, (3) allow unsigned key types.
+  // TODO(rybach): (1) don't use >= for key comparison, (2) allow unsigned key
+  // types.
   static constexpr I kCurrentKey = -1;
-  static constexpr I kEmptyKey = -2;
-  static constexpr I kDeletedKey = -3;
 
   class HashFunc {
    public:
@@ -244,12 +243,6 @@ class CompactHashBiTable {
 template <class I, class T, class H, class E, HSType HS>
 constexpr I CompactHashBiTable<I, T, H, E, HS>::kCurrentKey;
 
-template <class I, class T, class H, class E, HSType HS>
-constexpr I CompactHashBiTable<I, T, H, E, HS>::kEmptyKey;
-
-template <class I, class T, class H, class E, HSType HS>
-constexpr I CompactHashBiTable<I, T, H, E, HS>::kDeletedKey;
-
 // An implementation using a vector for the entry to ID mapping. It is passed a
 // function object FP that should fingerprint entries uniquely to an integer
 // that can used as a vector index. Normally, VectorBiTable constructs the FP
index 13b7cf8..e5c9f49 100644 (file)
@@ -117,7 +117,7 @@ class CacheState {
   // Accesses ref count; used by the caller.
   int RefCount() const { return ref_count_; }
 
-  void SetFinal(Weight weight) { final_ = std::move(weight); }
+  void SetFinal(Weight weight = Weight::One()) { final_ = std::move(weight); }
 
   void ReserveArcs(size_t n) { arcs_.reserve(n); }
 
@@ -902,7 +902,7 @@ class CacheBaseImpl : public FstImpl<typename State::Arc> {
     if (s >= nknown_states_) nknown_states_ = s + 1;
   }
 
-  void SetFinal(StateId s, Weight weight) {
+  void SetFinal(StateId s, Weight weight = Weight::One()) {
     auto *state = cache_store_->GetMutableState(s);
     state->SetFinal(std::move(weight));
     static constexpr auto flags = kCacheFinal | kCacheRecent;
@@ -1318,7 +1318,9 @@ class ExpanderCacheStore {
 
     void AddArc(Arc &&arc) { state->PushArc(std::move(arc)); }
 
-    void SetFinal(Weight weight) { state->SetFinal(std::move(weight)); }
+    void SetFinal(Weight weight = Weight::One()) {
+      state->SetFinal(std::move(weight));
+    }
   };
 };
 
index 13beea9..b0e377e 100644 (file)
@@ -43,8 +43,8 @@ void Closure(MutableFst<Arc> *fst, ClosureType closure_type) {
     fst->ReserveStates(fst->NumStates() + 1);
     const auto nstart = fst->AddState();
     fst->SetStart(nstart);
-    fst->SetFinal(nstart, Weight::One());
-    if (start != kNoLabel) fst->AddArc(nstart, Arc(0, 0, Weight::One(), start));
+    fst->SetFinal(nstart);
+    if (start != kNoLabel) fst->AddArc(nstart, Arc(0, 0, start));
   }
   fst->SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR),
                      kFstProperties);
index 402c87b..aee4fcf 100644 (file)
@@ -72,7 +72,7 @@ struct CompactFstOptions : public CacheOptions {
 //   // compacted using this compactor
 //   uint64 Properties() const;
 //   // Return a string identifying the type of compactor.
-//   static const string &Type();
+//   static const std::string &Type();
 //   // Return true if an error has occured.
 //   bool Error() const;
 //   // Writes a compactor to a file.
@@ -129,7 +129,7 @@ struct CompactFstOptions : public CacheOptions {
 //   uint64 Properties() const;
 //
 //   // Returns a string identifying the type of compactor.
-//   static const string &Type();
+//   static const std::string &Type();
 //
 //   // Writes a compactor to a file.
 //   bool Write(std::ostream &strm) const;
@@ -219,7 +219,7 @@ class DefaultCompactStore {
   bool Error() const { return error_; }
 
   // Returns a string identifying the type of data storage container.
-  static const string &Type();
+  static const std::string &Type();
 
  private:
   std::unique_ptr<MappedFile> states_region_;
@@ -454,8 +454,8 @@ bool DefaultCompactStore<Element, Unsigned>::Write(
 }
 
 template <class Element, class Unsigned>
-const string &DefaultCompactStore<Element, Unsigned>::Type() {
-  static const string *const type = new string("compact");
+const std::string &DefaultCompactStore<Element, Unsigned>::Type() {
+  static const std::string *const type = new std::string("compact");
   return *type;
 }
 
@@ -547,9 +547,9 @@ class DefaultCompactor {
 
   bool HasFixedOutdegree() const { return arc_compactor_->Size() != -1; }
 
-  static const string &Type() {
-    static const string *const type = [] {
-      string type = "compact";
+  static const std::string &Type() {
+    static const std::string *const type = [] {
+      std::string type = "compact";
       if (sizeof(U) != sizeof(uint32)) type += std::to_string(8 * sizeof(U));
       type += "_";
       type += C::Type();
@@ -557,7 +557,7 @@ class DefaultCompactor {
         type += "_";
         type += CompactStore::Type();
       }
-      return new string(type);
+      return new std::string(type);
     }();
     return *type;
   }
@@ -1086,7 +1086,7 @@ class CompactFst
   // Read a CompactFst from a file; return nullptr on error
   // Empty filename reads from standard input
   static CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Read(
-      const string &filename) {
+      const std::string &filename) {
     auto *impl = ImplToExpandedFst<Impl>::Read(filename);
     return impl ? new CompactFst<A, ArcCompactor, Unsigned, CompactStore,
                                  CacheStore>(std::shared_ptr<Impl>(impl))
@@ -1097,7 +1097,7 @@ class CompactFst
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<Arc>::WriteFile(filename);
   }
 
@@ -1192,7 +1192,7 @@ bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
   hdr.SetStart(fst.Start());
   hdr.SetNumStates(num_states);
   hdr.SetNumArcs(num_arcs);
-  string type = "compact";
+  std::string type = "compact";
   if (sizeof(Unsigned) != sizeof(uint32)) {
     type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
@@ -1246,7 +1246,7 @@ bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
   }
   strm.flush();
   if (!strm) {
-    LOG(ERROR) << "CompactFst write failed: " << opts.source;
+    LOG(ERROR) << "CompactFst::WriteFst: Write failed: " << opts.source;
     return false;
   }
   return true;
@@ -1346,17 +1346,15 @@ class StringCompactor {
 
   constexpr ssize_t Size() const { return 1; }
 
-  constexpr uint64 Properties() const {
-    return kString | kAcceptor | kUnweighted;
-  }
+  constexpr uint64 Properties() const { return kCompiledStringProperties; }
 
   bool Compatible(const Fst<Arc> &fst) const {
     const auto props = Properties();
     return fst.Properties(props, true) == props;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("string");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("string");
     return *type;
   }
 
@@ -1396,8 +1394,8 @@ class WeightedStringCompactor {
     return fst.Properties(props, true) == props;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("weighted_string");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("weighted_string");
     return *type;
   }
 
@@ -1436,8 +1434,9 @@ class UnweightedAcceptorCompactor {
     return fst.Properties(props, true) == props;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("unweighted_acceptor");
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string("unweighted_acceptor");
     return *type;
   }
 
@@ -1477,8 +1476,8 @@ class AcceptorCompactor {
     return fst.Properties(props, true) == props;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("acceptor");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("acceptor");
     return *type;
   }
 
@@ -1518,8 +1517,8 @@ class UnweightedCompactor {
     return fst.Properties(props, true) == props;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("unweighted");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("unweighted");
     return *type;
   }
 
index fc95b12..ba1afd0 100644 (file)
 #include <string>
 #include <vector>
 
-// Makes copy constructor and operator= private
-// Deprecated: now just use =delete.
-#define DISALLOW_COPY_AND_ASSIGN(type)    \
-  type(const type&);                      \
-  void operator=(const type&)
-
 #if defined(__GNUC__) || defined(__clang__)
 #define OPENFST_DEPRECATED(message) __attribute__((deprecated(message)))
 #elif defined(_MSC_VER)
@@ -44,8 +38,6 @@
 #include <fst/log.h>
 #include <fst/icu.h>
 
-using std::string;
-
 void FailedNewHandler();
 
 namespace fst {
@@ -83,18 +75,18 @@ class CheckSummer {
     }
   }
 
-  void Update(string const &data) {
+  void Update(std::string const &data) {
     for (int i = 0; i < data.size(); ++i) {
       check_sum_[(count_++) % kCheckSumLength] ^= data[i];
     }
   }
 
-  string Digest() { return check_sum_; }
+  std::string Digest() { return check_sum_; }
 
  private:
   static const int kCheckSumLength = 32;
   int count_;
-  string check_sum_;
+  std::string check_sum_;
 
   CheckSummer(const CheckSummer &) = delete;
   CheckSummer &operator=(const CheckSummer &) = delete;
index 64eebc0..13145e5 100644 (file)
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <string>
 #include <vector>
+
 #include <fst/log.h>
 
 #include <fst/fst.h>
index 09c81c7..8d53f2b 100644 (file)
@@ -53,7 +53,7 @@ class ConstFstImpl : public FstImpl<A> {
         narcs_(0),
         nstates_(0),
         start_(kNoStateId) {
-    string type = "const";
+    std::string type = "const";
     if (sizeof(Unsigned) != sizeof(uint32)) {
       type += std::to_string(CHAR_BIT * sizeof(Unsigned));
     }
@@ -146,7 +146,7 @@ constexpr int ConstFstImpl<Arc, Unsigned>::kMinFileVersion;
 template <class Arc, class Unsigned>
 ConstFstImpl<Arc, Unsigned>::ConstFstImpl(const Fst<Arc> &fst)
     : narcs_(0), nstates_(0) {
-  string type = "const";
+  std::string type = "const";
   if (sizeof(Unsigned) != sizeof(uint32)) {
     type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
@@ -275,7 +275,7 @@ class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
 
   // Read a ConstFst from a file; return nullptr on error; empty filename reads
   // from standard input.
-  static ConstFst<A, Unsigned> *Read(const string &filename) {
+  static ConstFst<A, Unsigned> *Read(const std::string &filename) {
     auto *impl = ImplToExpandedFst<Impl>::Read(filename);
     return impl ? new ConstFst<A, Unsigned>(std::shared_ptr<Impl>(impl))
                 : nullptr;
@@ -285,7 +285,7 @@ class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
     return WriteFst(*this, strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<Arc>::WriteFile(filename);
   }
 
@@ -352,7 +352,7 @@ bool ConstFst<Arc, Unsigned>::WriteFst(const FST &fst, std::ostream &strm,
   hdr.SetStart(fst.Start());
   hdr.SetNumStates(num_states);
   hdr.SetNumArcs(num_arcs);
-  string type = "const";
+  std::string type = "const";
   if (sizeof(Unsigned) != sizeof(uint32)) {
     type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
@@ -401,7 +401,7 @@ bool ConstFst<Arc, Unsigned>::WriteFst(const FST &fst, std::ostream &strm,
   }
   strm.flush();
   if (!strm) {
-    LOG(ERROR) << "ConstFst::WriteFst: write failed: " << opts.source;
+    LOG(ERROR) << "ConstFst::WriteFst: Write failed: " << opts.source;
     return false;
   }
   if (update_header) {
index 7e3ba37..bd01cce 100644 (file)
@@ -174,7 +174,7 @@ void RelationDeterminizeFilter<Arc, Relation>::InitLabelMap(
     if (arc.ilabel == label && arc.nextstate == nextstate) continue;
     DeterminizeArc<StateTuple> det_arc(arc);
     det_arc.dest_tuple->filter_state = FilterState(arc.nextstate);
-    label_map->insert(std::make_pair(arc.ilabel, det_arc));
+    label_map->emplace(arc.ilabel, det_arc);
     label = arc.ilabel;
     nextstate = arc.nextstate;
   }
index e7bdfd6..b0fba3a 100644 (file)
@@ -6,17 +6,17 @@
 //
 // The EditFst class enables non-destructive edit operations on a wrapped
 // ExpandedFst. The implementation uses copy-on-write semantics at the node
-// level: if a user has an underlying fst on which he or she wants to perform a
+// level: if a user has an underlying FST on which he or she wants to perform a
 // relatively small number of edits (read: mutations), then this implementation
 // will copy the edited node to an internal MutableFst and perform any edits in
 // situ on that copied node. This class supports all the methods of MutableFst
 // except for DeleteStates(const std::vector<StateId> &); thus, new nodes may
 // also be
-// added, and one may add transitions from existing nodes of the wrapped fst to
+// added, and one may add transitions from existing nodes of the wrapped FST to
 // new nodes.
 //
 // N.B.: The documentation for Fst::Copy(true) says that its behavior is
-// undefined if invoked on an fst that has already been accessed.  This class
+// undefined if invoked on an FST that has already been accessed. This class
 // requires that the Fst implementation it wraps provides consistent, reliable
 // behavior when its Copy(true) method is invoked, where consistent means
 // the graph structure, graph properties and state numbering and do not change.
@@ -40,17 +40,17 @@ namespace internal {
 // The EditFstData class is a container for all mutable data for EditFstImpl;
 // also, this class provides most of the actual implementation of what EditFst
 // does (that is, most of EditFstImpl's methods delegate to methods in this, the
-// EditFstData class).  Instances of this class are reference-counted and can be
+// EditFstData class). Instances of this class are reference-counted and can be
 // shared between otherwise independent EditFstImpl instances. This scheme
 // allows EditFstImpl to implement the thread-safe, copy-on-write semantics
 // required by Fst::Copy(true).
 //
 // template parameters:
-//   A the type of arc to use
-//   WrappedFstT the type of fst wrapped by the EditFst instance that
+//   A: the type of arc to use
+//   WrappedFstT: the type of FST wrapped by the EditFst instance that
 //     this EditFstData instance is backing
-//   MutableFstT the type of mutable fst to use internally for edited states;
-//     crucially, MutableFstT::Copy(false) *must* yield an fst that is
+//   MutableFstT: the type of mutable FST to use internally for edited states;
+//     crucially, MutableFstT::Copy(false) *must* yield an FST that is
 //     thread-safe for reading (VectorFst, for example, has this property)
 template <typename Arc, typename WrappedFstT = ExpandedFst<Arc>,
           typename MutableFstT = VectorFst<Arc>>
@@ -73,9 +73,9 @@ class EditFstData {
       std::istream &strm, const FstReadOptions &opts);
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
-    // Serialize all private data members of this class.
+    // Serializes all private data members of this class.
     FstWriteOptions edits_opts(opts);
-    edits_opts.write_header = true;  // Force writing contained header.
+    edits_opts.write_header = true;  // Forces writing contained header.
     edits_.Write(strm, edits_opts);
     WriteType(strm, external_to_internal_ids_);
     WriteType(strm, edited_final_weights_);
@@ -89,13 +89,13 @@ class EditFstData {
 
   StateId NumNewStates() const { return num_new_states_; }
 
-  // accessor methods for the fst holding edited states
+  // Accessor methods for the FST holding edited states.
   StateId EditedStart() const { return edits_.Start(); }
 
   Weight Final(StateId s, const WrappedFstT *wrapped) const {
     auto final_weight_it = GetFinalWeightIterator(s);
     if (final_weight_it == NotInFinalWeightMap()) {
-      auto it = GetEditedIdMapIterator(s);
+      const auto it = GetEditedIdMapIterator(s);
       return it == NotInEditedMap() ? wrapped->Final(s)
                                     : edits_.Final(it->second);
     } else {
@@ -104,19 +104,19 @@ class EditFstData {
   }
 
   size_t NumArcs(StateId s, const WrappedFstT *wrapped) const {
-    auto it = GetEditedIdMapIterator(s);
+    const auto it = GetEditedIdMapIterator(s);
     return it == NotInEditedMap() ? wrapped->NumArcs(s)
                                   : edits_.NumArcs(it->second);
   }
 
   size_t NumInputEpsilons(StateId s, const WrappedFstT *wrapped) const {
-    auto it = GetEditedIdMapIterator(s);
+    const auto it = GetEditedIdMapIterator(s);
     return it == NotInEditedMap() ? wrapped->NumInputEpsilons(s)
                                   : edits_.NumInputEpsilons(it->second);
   }
 
   size_t NumOutputEpsilons(StateId s, const WrappedFstT *wrapped) const {
-    auto it = GetEditedIdMapIterator(s);
+    const auto it = GetEditedIdMapIterator(s);
     return it == NotInEditedMap() ? wrapped->NumOutputEpsilons(s)
                                   : edits_.NumOutputEpsilons(it->second);
   }
@@ -131,27 +131,32 @@ class EditFstData {
   void SetStart(StateId s) { edits_.SetStart(s); }
 
   // Sets the final state for this FST.
-  Weight SetFinal(StateId s, Weight w, const WrappedFstT *wrapped) {
-    Weight old_weight = Final(s, wrapped);
-    auto it = GetEditedIdMapIterator(s);
+  Weight SetFinal(StateId s, Weight weight, const WrappedFstT *wrapped) {
+    const auto old_weight = Final(s, wrapped);
+    const auto it = GetEditedIdMapIterator(s);
     // If we haven't already edited state s, don't add it to edited_ (which can
     // be expensive if s has many transitions); just use the
     // edited_final_weights_ map.
     if (it == NotInEditedMap()) {
-      edited_final_weights_[s] = w;
+      edited_final_weights_[s] = weight;
     } else {
-      edits_.SetFinal(GetEditableInternalId(s, wrapped), w);
+      edits_.SetFinal(GetEditableInternalId(s, wrapped), weight);
     }
     return old_weight;
   }
 
-  // Adds a new state to this FST, initially with no arcs.
+  // Adds a new state to this FST.
   StateId AddState(StateId curr_num_states) {
-    StateId internal_state_id = edits_.AddState();
-    StateId external_state_id = curr_num_states;
-    external_to_internal_ids_[external_state_id] = internal_state_id;
-    num_new_states_++;
-    return external_state_id;
+    external_to_internal_ids_[curr_num_states] = edits_.AddState();
+    ++num_new_states_;
+    return curr_num_states;
+  }
+
+  // Adds new states to this FST.
+  void AddStates(StateId curr_num_states, size_t n) {
+    for (size_t i = 0; i < n; ++i) {
+      curr_num_states = AddState(curr_num_states);
+    }
   }
 
   // Adds the specified arc to the specified state of this FST.
@@ -161,7 +166,7 @@ class EditFstData {
     ArcIterator<MutableFstT> arc_it(edits_, internal_id);
     const Arc *prev_arc = nullptr;
     if (num_arcs > 0) {
-      // grab the final arc associated with this state in edits_
+      // Grabs the final arc associated with this state in edits_.
       arc_it.Seek(num_arcs - 1);
       prev_arc = &(arc_it.Value());
     }
@@ -191,15 +196,15 @@ class EditFstData {
   // Provides information for the generic arc iterator.
   void InitArcIterator(StateId s, ArcIteratorData<Arc> *data,
                        const WrappedFstT *wrapped) const {
-    auto id_map_it = GetEditedIdMapIterator(s);
-    if (id_map_it == NotInEditedMap()) {
+    const auto it = GetEditedIdMapIterator(s);
+    if (it == NotInEditedMap()) {
       VLOG(3) << "EditFstData::InitArcIterator: iterating on state " << s
-              << " of original fst";
+              << " of original FST";
       wrapped->InitArcIterator(s, data);
     } else {
       VLOG(2) << "EditFstData::InitArcIterator: iterating on edited state " << s
-              << " (internal state id: " << id_map_it->second << ")";
-      edits_.InitArcIterator(id_map_it->second, data);
+              << " (internal state ID: " << it->second << ")";
+      edits_.InitArcIterator(it->second, data);
     }
   }
 
@@ -210,19 +215,19 @@ class EditFstData {
         &edits_, GetEditableInternalId(s, wrapped));
   }
 
-  // Prints out the map from external to internal state id's (for debugging
+  // Prints out the map from external to internal state IDs (for debugging
   // purposes).
   void PrintMap() {
-    for (auto map_it = external_to_internal_ids_.begin();
-         map_it != NotInEditedMap(); ++map_it) {
-      LOG(INFO) << "(external,internal)=(" << map_it->first << ","
-                << map_it->second << ")";
+    for (auto it = external_to_internal_ids_.begin(); it != NotInEditedMap();
+         ++it) {
+      LOG(INFO) << "(external,internal)=(" << it->first << "," << it->second
+                << ")";
     }
   }
 
  private:
-  // Returns the iterator of the map from external to internal state id's
-  // of edits_ for the specified external state id.
+  // Returns the iterator of the map from external to internal state IDs
+  // of edits_ for the specified external state IDs.
   typename std::unordered_map<StateId, StateId>::const_iterator
       GetEditedIdMapIterator(StateId s) const {
     return external_to_internal_ids_.find(s);
@@ -245,13 +250,13 @@ class EditFstData {
 
   // Returns the internal state ID of the specified external ID if the state has
   // already been made editable, or else copies the state from wrapped_ to
-  // edits_ and returns the state id of the newly editable state in edits_.
+  // edits_ and returns the state ID of the newly editable state in edits_.
   StateId GetEditableInternalId(StateId s, const WrappedFstT *wrapped) {
     auto id_map_it = GetEditedIdMapIterator(s);
     if (id_map_it == NotInEditedMap()) {
       StateId new_internal_id = edits_.AddState();
       VLOG(2) << "EditFstData::GetEditableInternalId: editing state " << s
-              << " of original fst; new internal state id:" << new_internal_id;
+              << " of original FST; new internal state id:" << new_internal_id;
       external_to_internal_ids_[s] = new_internal_id;
       for (ArcIterator<Fst<Arc>> arc_iterator(*wrapped, s);
            !arc_iterator.Done(); arc_iterator.Next()) {
@@ -279,11 +284,11 @@ class EditFstData {
   // appear in edits_.
   std::unordered_map<StateId, StateId> external_to_internal_ids_;
   // A mapping from external state IDs to final state weights assigned to
-  // those states.  The states in this map are *only* those whose final weight
+  // those states. The states in this map are *only* those whose final weight
   // has been modified; if any other part of the state has been modified,
   // the entire state is copied to edits_, and all modifications reside there.
   std::unordered_map<StateId, Weight> edited_final_weights_;
-  // The number of new states added to this mutable fst impl, which is <= the
+  // The number of new states added to this mutable FST impl, which is <= the
   // number of states in edits_ (since edits_ contains both edited *and* new
   // states).
   StateId num_new_states_;
@@ -295,11 +300,10 @@ EditFstData<A, WrappedFstT, MutableFstT> *
 EditFstData<A, WrappedFstT, MutableFstT>::Read(std::istream &strm,
                                                const FstReadOptions &opts) {
   auto *data = new EditFstData<A, WrappedFstT, MutableFstT>();
-  // next read in MutabelFstT machine that stores edits
+  // Next read in MutabelFstT machine that stores edits
   FstReadOptions edits_opts(opts);
   // Contained header was written out, so read it in.
   edits_opts.header = nullptr;
-
   // Because our internal representation of edited states is a solid object
   // of type MutableFstT (defaults to VectorFst<A>) and not a pointer,
   // and because the static Read method allocates a new object on the heap,
@@ -324,20 +328,20 @@ EditFstData<A, WrappedFstT, MutableFstT>::Read(std::istream &strm,
 
 // This class enables non-destructive edit operations on a wrapped ExpandedFst.
 // The implementation uses copy-on-write semantics at the node level: if a user
-// has an underlying fst on which he or she wants to perform a relatively small
+// has an underlying FST on which he or she wants to perform a relatively small
 // number of edits (read: mutations), then this implementation will copy the
 // edited node to an internal MutableFst and perform any edits in situ on that
 // copied node. This class supports all the methods of MutableFst except for
 // DeleteStates(const std::vector<StateId> &); thus, new nodes may also be
 // added, and
-// one may add transitions from existing nodes of the wrapped fst to new nodes.
+// one may add transitions from existing nodes of the wrapped FST to new nodes.
 //
 // template parameters:
-//   A the type of arc to use
-//   WrappedFstT the type of fst wrapped by the EditFst instance that
+//   A: the type of arc to use
+//   WrappedFstT: the type of FST wrapped by the EditFst instance that
 //     this EditFstImpl instance is backing
-//   MutableFstT the type of mutable fst to use internally for edited states;
-//     crucially, MutableFstT::Copy(false) *must* yield an fst that is
+//   MutableFstT: the type of mutable FST to use internally for edited states;
+//     crucially, MutableFstT::Copy(false) must yield an FST that is
 //     thread-safe for reading (VectorFst, for example, has this property)
 template <typename A, typename WrappedFstT = ExpandedFst<A>,
           typename MutableFstT = VectorFst<A>>
@@ -353,7 +357,7 @@ class EditFstImpl : public FstImpl<A> {
   using FstImpl<Arc>::WriteHeader;
 
   // Constructs an editable FST implementation with no states. Effectively, this
-  // initially-empty fst will in every way mimic the behavior of a
+  // initially-empty FST will in every way mimic the behavior of a
   // VectorFst---more precisely, a VectorFstImpl instance---but with slightly
   // slower performance (by a constant factor), due to the fact that
   // this class maintains a mapping between external state id's and
@@ -371,10 +375,10 @@ class EditFstImpl : public FstImpl<A> {
   // This library uses the pointer-to-implementation or "PIMPL" design pattern.
   // In particular, to make it convenient to bind an implementation class to its
   // interface, there are a pair of template "binder" classes, one for immutable
-  // and one for mutable fst's (ImplToFst and ImplToMutableFst, respectively).
+  // and one for mutable FSTs (ImplToFst and ImplToMutableFst, respectively).
   // 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
+  // taking a const Fst<A> reference. Accordingly, the constructor here must
   // perform a static_cast to the WrappedFstT type required by EditFst and
   // therefore EditFstImpl.
   explicit EditFstImpl(const Fst<Arc> &wrapped)
@@ -431,9 +435,9 @@ class EditFstImpl : public FstImpl<A> {
     header_opts.write_isymbols = false;
     header_opts.write_osymbols = false;
     WriteHeader(strm, header_opts, kFileVersion, &hdr);
-    // First, serializes the wrapped FST to stream.
+    // Serializes the wrapped FST to stream.
     FstWriteOptions wrapped_opts(opts);
-    // Forcse writing the contained header.
+    // Forces writing the contained header.
     wrapped_opts.write_header = true;
     wrapped_->Write(strm, wrapped_opts);
     data_->Write(strm, opts);
@@ -452,7 +456,7 @@ class EditFstImpl : public FstImpl<A> {
     SetProperties(SetStartProperties(FstImpl<Arc>::Properties()));
   }
 
-  // Sets the final state for this fst.
+  // Sets the final state for this FST.
   void SetFinal(StateId s, Weight weight) {
     MutateCheck();
     Weight old_weight = data_->SetFinal(s, weight, wrapped_.get());
@@ -460,14 +464,21 @@ class EditFstImpl : public FstImpl<A> {
         SetFinalProperties(FstImpl<Arc>::Properties(), old_weight, weight));
   }
 
-  // Adds a new state to this fst, initially with no arcs.
+  // Adds a new state to this FST.
   StateId AddState() {
     MutateCheck();
     SetProperties(AddStateProperties(FstImpl<Arc>::Properties()));
     return data_->AddState(NumStates());
   }
 
-  // Adds the specified arc to the specified state of this fst.
+  // Adds new states to this FST.
+  void AddStates(size_t n) {
+    MutateCheck();
+    SetProperties(AddStateProperties(FstImpl<Arc>::Properties()));
+    return data_->AddStates(NumStates(), n);
+  }
+
+  // Adds the specified arc to the specified state of this FST.
   void AddArc(StateId s, const Arc &arc) {
     MutateCheck();
     const auto *prev_arc = data_->AddArc(s, arc, wrapped_.get());
@@ -481,7 +492,7 @@ class EditFstImpl : public FstImpl<A> {
     SetProperties(kError, kError);
   }
 
-  // Deletes all states in this fst.
+  // Deletes all states in this FST.
   void DeleteStates();
 
   // Removes all but the first n outgoing arcs of the specified state.
@@ -541,13 +552,13 @@ class EditFstImpl : public FstImpl<A> {
 
   // This method ensures that any operations that alter the mutable data
   // portion of this EditFstImpl cause the data_ member to be copied when its
-  // reference count is greater than 1.  Note that this method is distinct from
+  // reference count is greater than 1. Note that this method is distinct from
   // MutableFst::Mutate, which gets invoked whenever one of the basic mutation
   // methods defined in MutableFst is invoked, such as SetInputSymbols.
   // The MutateCheck here in EditFstImpl is invoked whenever one of the
   // mutating methods specifically related to the types of edits provided
   // by EditFst is performed, such as changing an arc of an existing state
-  // of the wrapped fst via a MutableArcIterator, or adding a new state via
+  // of the wrapped FST via a MutableArcIterator, or adding a new state via
   // AddState().
   void MutateCheck() {
     if (!data_.unique()) {
@@ -607,7 +618,7 @@ EditFstImpl<Arc, WrappedFstT, MutableFstT>::Read(std::istream &strm,
 
 }  // namespace internal
 
-// Concrete, editable FST.  This class attaches interface to implementation.
+// Concrete, editable FST. This class attaches interface to implementation.
 template <typename A, typename WrappedFstT = ExpandedFst<A>,
           typename MutableFstT = VectorFst<A>>
 class EditFst : public ImplToMutableFst<
@@ -661,7 +672,8 @@ class EditFst : public ImplToMutableFst<
 
   // Reads an EditFst from a file, returning nullptr on error. If the filename
   // argument is an empty string, it reads from standard input.
-  static EditFst<Arc, WrappedFstT, MutableFstT> *Read(const string &filename) {
+  static EditFst<Arc, WrappedFstT, MutableFstT> *Read(
+      const std::string &filename) {
     auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(filename);
     return impl ? new EditFst<Arc, WrappedFstT, MutableFstT>(
                       std::shared_ptr<Impl>(impl))
@@ -672,7 +684,7 @@ class EditFst : public ImplToMutableFst<
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<Arc>::WriteFile(filename);
   }
 
index f251bbf..14e307d 100644 (file)
@@ -110,8 +110,8 @@ class EncodeTable {
     std::unique_ptr<Tuple> tuple(
         new Tuple(arc.ilabel, flags_ & kEncodeLabels ? arc.olabel : 0,
                   flags_ & kEncodeWeights ? arc.weight : Weight::One()));
-    auto insert_result = encode_hash_.insert(
-        std::make_pair(tuple.get(), encode_tuples_.size() + 1));
+    auto insert_result =
+        encode_hash_.emplace(tuple.get(), encode_tuples_.size() + 1);
     if (insert_result.second) encode_tuples_.push_back(std::move(tuple));
     return insert_result.first->second;
   }
@@ -135,9 +135,9 @@ class EncodeTable {
 
   size_t Size() const { return encode_tuples_.size(); }
 
-  bool Write(std::ostream &strm, const string &source) const;
+  bool Write(std::ostream &strm, const std::string &source) const;
 
-  static EncodeTable<Arc> *Read(std::istream &strm, const string &source);
+  static EncodeTable<Arc> *Read(std::istream &strm, const std::string &source);
 
   uint32 Flags() const { return flags_ & kEncodeFlags; }
 
@@ -178,7 +178,7 @@ class EncodeTable {
 
 template <class Arc>
 bool EncodeTable<Arc>::Write(std::ostream &strm,
-                                  const string &source) const {
+                             const std::string &source) const {
   WriteType(strm, kEncodeMagicNumber);
   WriteType(strm, flags_);
   const int64 size = encode_tuples_.size();
@@ -200,7 +200,7 @@ bool EncodeTable<Arc>::Write(std::ostream &strm,
 
 template <class Arc>
 EncodeTable<Arc> *EncodeTable<Arc>::Read(std::istream &strm,
-                                         const string &source) {
+                                         const std::string &source) {
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
   if (magic_number != kEncodeMagicNumber) {
@@ -316,11 +316,11 @@ class EncodeMapper {
 
   EncodeType Type() const { return type_; }
 
-  bool Write(std::ostream &strm, const string &source) const {
+  bool Write(std::ostream &strm, const std::string &source) const {
     return table_->Write(strm, source);
   }
 
-  bool Write(const string &filename) const {
+  bool Write(const std::string &filename) const {
     std::ofstream strm(filename,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm) {
@@ -330,13 +330,13 @@ class EncodeMapper {
     return Write(strm, filename);
   }
 
-  static EncodeMapper<Arc> *Read(std::istream &strm, const string &source,
-                               EncodeType type = ENCODE) {
+  static EncodeMapper<Arc> *Read(std::istream &strm, const std::string &source,
+                                 EncodeType type = ENCODE) {
     auto *table = internal::EncodeTable<Arc>::Read(strm, source);
     return table ? new EncodeMapper(table->Flags(), type, table) : nullptr;
   }
 
-  static EncodeMapper<Arc> *Read(const string &filename,
+  static EncodeMapper<Arc> *Read(const std::string &filename,
                                  EncodeType type = ENCODE) {
     std::ifstream strm(filename,
                             std::ios_base::in | std::ios_base::binary);
index cf3fdb6..fc81ecd 100644 (file)
@@ -9,8 +9,8 @@
 #include <algorithm>
 #include <deque>
 #include <unordered_map>
-#include <utility>
 #include <vector>
+
 #include <fst/log.h>
 
 #include <fst/encode.h>
@@ -174,7 +174,7 @@ bool Equivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
   // Main loop: explores the two acceptors in a breadth-first manner, updating
   // the equivalence relation on the statesets. Loop invariant: each block of
   // the states contains either final states only or non-final states only.
-  for (q.push_back(std::make_pair(s1, s2)); ret && !q.empty(); q.pop_front()) {
+  for (q.emplace_back(s1, s2); ret && !q.empty(); q.pop_front()) {
     s1 = q.front().first;
     s2 = q.front().second;
     // Representatives of the equivalence classes of s1/s2.
index 2c7d514..2392895 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_EXPANDED_FST_H_
 
 #include <sys/types.h>
+
 #include <istream>
 #include <memory>
 #include <string>
@@ -60,7 +61,7 @@ class ExpandedFst : public Fst<A> {
 
   // Read an ExpandedFst from a file; return NULL on error.
   // Empty filename reads from standard input.
-  static ExpandedFst<Arc> *Read(const string &filename) {
+  static ExpandedFst<Arc> *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -133,7 +134,7 @@ class ImplToExpandedFst : public ImplToFst<Impl, FST> {
 
   // Read FST implementation from a file; return NULL on error.
   // Empty filename reads from standard input.
-  static Impl *Read(const string &filename) {
+  static Impl *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -165,10 +166,10 @@ typename Arc::StateId CountStates(const Fst<Arc> &fst) {
 }
 
 // Function to return the number of arcs in an FST.
-template <class Arc>
-typename Arc::StateId CountArcs(const Fst<Arc> &fst) {
+template <class F>
+size_t CountArcs(const F &fst) {
   size_t narcs = 0;
-  for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) {
+  for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) {
     narcs += fst.NumArcs(siter.Value());
   }
   return narcs;
diff --git a/src/include/fst/expander-cache.h b/src/include/fst/expander-cache.h
new file mode 100644 (file)
index 0000000..36acae2
--- /dev/null
@@ -0,0 +1,226 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Cache implementations for ExpanderFst.
+//
+// Expander caches must expose a State type and a FindOrExpand template method:
+//
+// class ExpanderCache {
+//  public:
+//   class State;
+//
+//   template <Expander>
+//   State* FindOrExpander(Expander& expander, StateId id) {
+//     if (id is found in cache) return cached_state;
+//
+//     // Use the provided expander to create a new cached state and cache it.
+//     expander.Expand(id, &new_state);
+//     insert new_state into cache;
+//     return new_state;
+//   }
+// };
+//
+// Cache implementations must be copyable and assignable. It is up to the
+// implementation whether this means it will discard the contents of the cache,
+// copy all of the cache, share some of the cache etc. It is *REQUIRED* that the
+// copy be "safe", the copy and the original must be usable from concurrent
+// threads without accessing any internally shared state.
+
+#ifndef FST_EXPANDER_CACHE_H_
+#define FST_EXPANDER_CACHE_H_
+
+#include <deque>
+#include <memory>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include <fst/cache.h>
+#include <fst/fst.h>
+#include <unordered_map>
+
+namespace fst {
+
+// Stateful allocators can't be used without careful handling in threaded
+// contexts, so arbitrary stl allocators aren't supported here.
+template <class A>
+class SimpleVectorCacheState {
+ public:
+  using Arc = A;
+  using Weight = typename Arc::Weight;
+  using StateId = typename Arc::StateId;
+
+  void Reset() {
+    final_ = Weight::Zero();
+    niepsilons_ = 0;
+    noepsilons_ = 0;
+    arcs_.clear();
+  }
+
+  Weight Final() const { return final_; }
+
+  size_t NumInputEpsilons() const { return niepsilons_; }
+
+  size_t NumOutputEpsilons() const { return noepsilons_; }
+
+  size_t NumArcs() const { return arcs_.size(); }
+
+  const Arc &GetArc(size_t n) const { return arcs_[n]; }
+
+  const Arc *Arcs() const { return arcs_.empty() ? nullptr : &arcs_[0]; }
+
+  void SetFinal(Weight final) { final_ = final; }
+
+  void ReserveArcs(size_t n) { arcs_.reserve(n); }
+
+  void AddArc(const Arc &arc) {
+    if (arc.ilabel == 0) ++niepsilons_;
+    if (arc.olabel == 0) ++noepsilons_;
+    arcs_.push_back(arc);
+  }
+
+  void AddArc(Arc &&arc) {
+    if (arc.ilabel == 0) ++niepsilons_;
+    if (arc.olabel == 0) ++noepsilons_;
+    arcs_.push_back(std::move(arc));
+  }
+
+  int *MutableRefCount() const { return nullptr; }
+
+ private:
+  Weight final_ = Weight::Zero();
+  size_t niepsilons_ = 0;  // Number of input epsilons.
+  size_t noepsilons_ = 0;  // Number of output epsilons.
+  std::vector<Arc> arcs_;
+};
+
+template <class A>
+class NoGcKeepOneExpanderCache {
+ public:
+  using Arc = A;
+  using StateId = typename Arc::StateId;
+
+  // Reference-counted state.
+  class State : public SimpleVectorCacheState<Arc> {
+   public:
+    int *MutableRefCount() { return &ref_count_; }
+
+    void Reset() {
+      SimpleVectorCacheState<Arc>::Reset();
+      ref_count_ = 0;
+    }
+
+   private:
+    int ref_count_ = 0;
+
+    friend class NoGcKeepOneExpanderCache;
+  };
+
+  NoGcKeepOneExpanderCache() : state_(new State) {}
+
+  NoGcKeepOneExpanderCache(const NoGcKeepOneExpanderCache &copy)
+      : state_(new State(*copy.state_)) {}
+
+  template <class Expander>
+  State *FindOrExpand(Expander &expander, StateId state_id) {
+    if (state_id == state_id_) return state_.get();
+    if (state_->ref_count_ > 0) cache_[state_id_] = std::move(state_);
+    state_id_ = state_id;
+    if (cache_.empty()) {
+      state_->Reset();
+      expander.Expand(state_id_, state_.get());
+      return state_.get();
+    }
+    auto i = cache_.find(state_id_);
+    if (i != cache_.end()) state_ = std::move(i->second);
+    if (state_ == nullptr) {
+      state_.reset(new State);
+      expander.Expand(state_id_, state_.get());
+    }
+    return state_.get();
+  }
+
+  StateId state_id_ = kNoStateId;
+  std::unique_ptr<State> state_;
+  std::unordered_map<StateId, std::unique_ptr<State>> cache_;
+};
+
+template <class A>
+class HashExpanderCache {
+ public:
+  using Arc = A;
+  using StateId = typename Arc::StateId;
+
+  using State = SimpleVectorCacheState<Arc>;
+
+  HashExpanderCache(const HashExpanderCache &copy) { *this = copy; }
+
+  HashExpanderCache &operator=(const HashExpanderCache &copy) {
+    for (const auto &kv : copy.cache_) cache_[kv.first] = new State(*kv.second);
+    return *this;
+  }
+
+  ~HashExpanderCache() {
+    for (auto i : cache_) delete i.second;
+  }
+
+  template <class Expander>
+  State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
+    auto it = cache_.insert(std::pair<StateId, State*>(state_id, nullptr));
+    if (!it.second) return it.first->second;
+    auto *state = new State;
+    it.first->second = state;
+    expander.Expand(state_id, state);
+    return state;
+  }
+
+ private:
+  std::unordered_map<StateId, State *> cache_;
+};
+
+template <class A>
+class VectorExpanderCache {
+ public:
+  using Arc = A;
+  using StateId = typename Arc::StateId;
+
+  using State = SimpleVectorCacheState<Arc>;
+
+  VectorExpanderCache() : vec_(0, nullptr) {}
+
+  VectorExpanderCache(const VectorExpanderCache &copy) { *this = copy; }
+
+  VectorExpanderCache &operator=(const VectorExpanderCache &copy) {
+    vec_.resize(copy.vec_.size());
+    for (StateId i = 0; i < copy.vec_.size(); ++i) {
+      const auto *state = copy.vec_[i];
+      if (state != nullptr) {
+        states_.emplace_back(*state);
+        vec_[i] = &states_.back();
+      }
+    }
+    return *this;
+  }
+
+  template <class Expander>
+  State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
+    if (state_id >= vec_.size()) vec_.resize(state_id + 1);
+    auto **slot = &vec_[state_id];
+    if (*slot == nullptr) {
+      states_.emplace_back();
+      *slot = &states_.back();
+      expander.Expand(state_id, *slot);
+    }
+    return *slot;
+  }
+
+ private:
+  std::deque<State> states_;
+  std::vector<State *> vec_;
+};
+
+template <class Expander>
+using DefaultExpanderCache = VectorExpanderCache<typename Expander::Arc>;
+
+}  // namespace fst
+#endif  // FST_EXPANDER_CACHE_H_
index f996cbc..ae4266f 100644 (file)
@@ -69,9 +69,9 @@ class ExpectationWeight : public PairWeight<X1, X2> {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string("expectation_" + X1::Type() + "_" + X2::Type());
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string("expectation_" + X1::Type() + "_" + X2::Type());
     return *type;
   }
 
diff --git a/src/include/fst/extensions/compress/compress-script.h b/src/include/fst/extensions/compress/compress-script.h
deleted file mode 100644 (file)
index bad238a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Declarations of 'scriptable' versions of compression operations, that is,
-// those that can be called with FstClass-type arguments.
-
-#ifndef FST_EXTENSIONS_COMPRESS_COMPRESS_SCRIPT_H_
-#define FST_EXTENSIONS_COMPRESS_COMPRESS_SCRIPT_H_
-
-#include <string>
-#include <tuple>
-
-#include <fst/log.h>
-#include <fst/extensions/compress/compress.h>
-#include <fst/mutable-fst.h>
-#include <fst/util.h>
-#include <fst/script/fst-class.h>
-
-namespace fst {
-namespace script {
-
-typedef std::tuple<const FstClass &, const string &, const bool> CompressArgs;
-
-template <class Arc>
-void Compress(CompressArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
-  const string &filename = std::get<1>(*args);
-  const bool gzip = std::get<2>(*args);
-
-  if (!fst::Compress(fst, filename, gzip)) FSTERROR() << "Compress: failed";
-}
-
-void Compress(const FstClass &fst, const string &filename, const bool gzip);
-
-typedef std::tuple<const string &, MutableFstClass *, const bool>
-    DecompressArgs;
-
-template <class Arc>
-void Decompress(DecompressArgs *args) {
-  const string &filename = std::get<0>(*args);
-  MutableFst<Arc> *fst = std::get<1>(*args)->GetMutableFst<Arc>();
-  const bool gzip = std::get<2>(*args);
-
-  if (!fst::Decompress(filename, fst, gzip))
-    FSTERROR() << "Decompress: failed";
-}
-
-void Decompress(const string &filename, MutableFstClass *fst, const bool gzip);
-
-}  // namespace script
-}  // namespace fst
-
-#endif  // FST_EXTENSIONS_COMPRESS_COMPRESS_SCRIPT_H_
index aa94848..5675c64 100644 (file)
@@ -13,7 +13,6 @@
 #include <memory>
 #include <queue>
 #include <string>
-#include <utility>
 #include <vector>
 
 #include <fst/compat.h>
@@ -21,6 +20,7 @@
 #include <fst/extensions/compress/elias.h>
 #include <fst/extensions/compress/gzfile.h>
 #include <fst/encode.h>
+#include <fstream>
 #include <fst/fst.h>
 #include <fst/mutable-fst.h>
 #include <fst/statesort.h>
@@ -29,16 +29,16 @@ namespace fst {
 
 // Identifies stream data as a vanilla compressed FST.
 static const int32 kCompressMagicNumber = 1858869554;
-// Identifies stream data as (probably) a Gzip file accidentally read from
-// vanilla stream, without gzip support.
+// Identifies stream data as (probably) a Gzip file accidentally read from a
+// vanilla stream, without gzip support.
 static const int32 kGzipMagicNumber = 0x8b1f;
 // Selects the two most significant bytes.
 constexpr uint32 kGzipMask = 0xffffffff >> 16;
 
 namespace internal {
 
-// Expands a Lempel Ziv code and returns the set of code words. expanded_code[i]
-// is the i^th Lempel Ziv codeword.
+// Expands a Lempel Ziv code and returns the set of code words where
+// expanded_code[i] is the i^th Lempel Ziv codeword.
 template <class Var, class Edge>
 bool ExpandLZCode(const std::vector<std::pair<Var, Edge>> &code,
                   std::vector<std::vector<Edge>> *expanded_code) {
@@ -48,16 +48,15 @@ bool ExpandLZCode(const std::vector<std::pair<Var, Edge>> &code,
       LOG(ERROR) << "ExpandLZCode: Not a valid code";
       return false;
     }
+    auto &codeword = (*expanded_code)[i];
     if (code[i].first == 0) {
-      (*expanded_code)[i].resize(1, code[i].second);
+      codeword.resize(1, code[i].second);
     } else {
-      (*expanded_code)[i].resize((*expanded_code)[code[i].first - 1].size() +
-                                 1);
-      std::copy((*expanded_code)[code[i].first - 1].begin(),
-                (*expanded_code)[code[i].first - 1].end(),
-                (*expanded_code)[i].begin());
-      (*expanded_code)[i][(*expanded_code)[code[i].first - 1].size()] =
-          code[i].second;
+      const auto &other_codeword = (*expanded_code)[code[i].first - 1];
+      codeword.resize(other_codeword.size() + 1);
+      std::copy(other_codeword.cbegin(), other_codeword.cend(),
+                codeword.begin());
+      codeword[other_codeword.size()] = code[i].second;
     }
   }
   return true;
@@ -65,29 +64,28 @@ bool ExpandLZCode(const std::vector<std::pair<Var, Edge>> &code,
 
 }  // namespace internal
 
-// Lempel Ziv on data structure Edge, with a less than operator
-// EdgeLessThan and an equals operator  EdgeEquals.
-// Edge has a value defaultedge which it never takes and
-// Edge is defined, it is initialized to defaultedge
+// Lempel Ziv on data structure Edge, with a less-than operator EdgeLessThan and
+// an equals operator EdgeEquals.
 template <class Var, class Edge, class EdgeLessThan, class EdgeEquals>
 class LempelZiv {
  public:
   LempelZiv() : dict_number_(0), default_edge_() {
     root_.current_number = dict_number_++;
     root_.current_edge = default_edge_;
-    decode_vector_.push_back(std::make_pair(0, default_edge_));
+    decode_vector_.emplace_back(0, default_edge_);
   }
-  // Encodes a vector input into output
+
+  // Encodes a vector input into output.
   void BatchEncode(const std::vector<Edge> &input,
                    std::vector<std::pair<Var, Edge>> *output);
 
-  // Decodes codedvector to output. Returns false if
-  // the index exceeds the size.
+  // Decodes codedvector to output, returning false if the index exceeds the
+  // size.
   bool BatchDecode(const std::vector<std::pair<Var, Edge>> &input,
                    std::vector<Edge> *output);
 
-  // Decodes a single dictionary element. Returns false
-  // if the index exceeds the size.
+  // Decodes a single dictionary element, returning false if the index exceeds
+  // the size.
   bool SingleDecode(const Var &index, Edge *output) {
     if (index >= decode_vector_.size()) {
       LOG(ERROR) << "LempelZiv::SingleDecode: "
@@ -100,21 +98,13 @@ class LempelZiv {
   }
 
   ~LempelZiv() {
-    for (auto it = (root_.next_number).begin(); it != (root_.next_number).end();
+    for (auto it = root_.next_number.begin(); it != root_.next_number.end();
          ++it) {
       CleanUp(it->second);
     }
   }
-  // Adds a single dictionary element while decoding
-  //  void AddDictElement(const std::pair<Var, Edge> &newdict) {
-  //    EdgeEquals InstEdgeEquals;
-  //  if (InstEdgeEquals(newdict.second, default_edge_) != 1)
-  //     decode_vector_.push_back(newdict);
-  //  }
 
  private:
-  // Node datastructure is used for encoding
-
   struct Node {
     Var current_number;
     Edge current_edge;
@@ -122,15 +112,15 @@ class LempelZiv {
   };
 
   void CleanUp(Node *temp) {
-    for (auto it = (temp->next_number).begin(); it != (temp->next_number).end();
+    for (auto it = temp->next_number.begin(); it != temp->next_number.end();
          ++it) {
       CleanUp(it->second);
     }
     delete temp;
   }
+
   Node root_;
   Var dict_number_;
-  // decode_vector_ is used for decoding
   std::vector<std::pair<Var, Edge>> decode_vector_;
   Edge default_edge_;
 };
@@ -138,45 +128,41 @@ class LempelZiv {
 template <class Var, class Edge, class EdgeLessThan, class EdgeEquals>
 void LempelZiv<Var, Edge, EdgeLessThan, EdgeEquals>::BatchEncode(
     const std::vector<Edge> &input, std::vector<std::pair<Var, Edge>> *output) {
-  for (typename std::vector<Edge>::const_iterator it = input.begin();
-       it != input.end(); ++it) {
-    Node *temp_node = &root_;
-    while (it != input.end()) {
-      auto next = (temp_node->next_number).find(*it);
-      if (next != (temp_node->next_number).end()) {
+  for (auto it = input.cbegin(); it != input.cend(); ++it) {
+    auto *temp_node = &root_;
+    while (it != input.cend()) {
+      auto next = temp_node->next_number.find(*it);
+      if (next != temp_node->next_number.cend()) {
         temp_node = next->second;
         ++it;
       } else {
         break;
       }
     }
-    if (it == input.end() && temp_node->current_number != 0) {
-      output->push_back(
-          std::make_pair(temp_node->current_number, default_edge_));
-    } else if (it != input.end()) {
-      output->push_back(std::make_pair(temp_node->current_number, *it));
-      Node *new_node = new (Node);
+    if (it == input.cend() && temp_node->current_number != 0) {
+      output->emplace_back(temp_node->current_number, default_edge_);
+    } else if (it != input.cend()) {
+      output->emplace_back(temp_node->current_number, *it);
+      auto *new_node = new Node();
       new_node->current_number = dict_number_++;
       new_node->current_edge = *it;
-      (temp_node->next_number)[*it] = new_node;
+      temp_node->next_number[*it] = new_node;
     }
-    if (it == input.end()) break;
+    if (it == input.cend()) break;
   }
 }
 
 template <class Var, class Edge, class EdgeLessThan, class EdgeEquals>
 bool LempelZiv<Var, Edge, EdgeLessThan, EdgeEquals>::BatchDecode(
     const std::vector<std::pair<Var, Edge>> &input, std::vector<Edge> *output) {
-  for (typename std::vector<std::pair<Var, Edge>>::const_iterator it =
-           input.begin();
-       it != input.end(); ++it) {
+  for (auto it = input.cbegin(); it != input.cend(); ++it) {
     std::vector<Edge> temp_output;
     EdgeEquals InstEdgeEquals;
     if (InstEdgeEquals(it->second, default_edge_) != 1) {
       decode_vector_.push_back(*it);
       temp_output.push_back(it->second);
     }
-    Var temp_integer = it->first;
+    auto temp_integer = it->first;
     if (temp_integer >= decode_vector_.size()) {
       LOG(ERROR) << "LempelZiv::BatchDecode: "
                  << "Index exceeded the dictionary size";
@@ -187,69 +173,60 @@ bool LempelZiv<Var, Edge, EdgeLessThan, EdgeEquals>::BatchDecode(
         temp_integer = decode_vector_[temp_integer].first;
       }
       std::reverse(temp_output.begin(), temp_output.end());
-      output->insert(output->end(), temp_output.begin(), temp_output.end());
+      output->insert(output->cend(), temp_output.begin(), temp_output.end());
     }
   }
   return true;
 }
 
-// The main Compressor class
 template <class Arc>
 class Compressor {
  public:
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Label Label;
-  typedef typename Arc::Weight Weight;
+  using Label = typename Arc::Label;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
 
-  Compressor() {}
+  Compressor() = default;
 
-  // Compresses fst into a boolean vector code. Returns true on sucesss.
+  // Compresses an FST into a boolean vector code, returning true on success.
   bool Compress(const Fst<Arc> &fst, std::ostream &strm);
 
-  // Decompresses the boolean vector into Fst. Returns true on sucesss.
-  bool Decompress(std::istream &strm, const string &source,
+  // Decompresses the boolean vector into an FST, returning true on success.
+  bool Decompress(std::istream &strm, const std::string &source,
                   MutableFst<Arc> *fst);
 
-  // Finds the BFS order of a fst
+  // Computes the BFS order of a FST.
   void BfsOrder(const ExpandedFst<Arc> &fst, std::vector<StateId> *order);
 
-  // Preprocessing step to convert fst to a isomorphic fst
-  // Returns a preproccess fst and a dictionary
+  // Preprocessing step to convert an FST to a isomorphic FST.
   void Preprocess(const Fst<Arc> &fst, MutableFst<Arc> *preprocessedfst,
                   EncodeMapper<Arc> *encoder);
 
-  // Performs Lempel Ziv and outputs a stream of integers
-  // and sends it to a stream
+  // Performs Lempel Ziv and outputs a stream of integers.
   void EncodeProcessedFst(const ExpandedFst<Arc> &fst, std::ostream &strm);
 
-  // Decodes fst from the stream
+  // Decodes FST from the stream.
   void DecodeProcessedFst(const std::vector<StateId> &input,
                           MutableFst<Arc> *fst, bool unweighted);
 
-  // Converts buffer_code_ to uint8 and writes to a stream.
-
-  // Writes the boolean file to the stream
+  // Writes the boolean file to the stream.
   void WriteToStream(std::ostream &strm);
 
-  // Writes the weights to the stream
+  // Writes the weights to the stream.
   void WriteWeight(const std::vector<Weight> &input, std::ostream &strm);
 
   void ReadWeight(std::istream &strm, std::vector<Weight> *output);
 
-  // Same as fst::Decode without the line RmFinalEpsilon(fst)
+  // Same as fst::Decode, but doesn't remove the final epsilons.
   void DecodeForCompress(MutableFst<Arc> *fst, const EncodeMapper<Arc> &mapper);
 
-  // Updates the buffer_code_
+  // Updates buffer_code_.
   template <class CVar>
   void WriteToBuffer(CVar input) {
     std::vector<bool> current_code;
     Elias<CVar>::DeltaEncode(input, &current_code);
-    if (!buffer_code_.empty()) {
-      buffer_code_.insert(buffer_code_.end(), current_code.begin(),
-                          current_code.end());
-    } else {
-      buffer_code_.assign(current_code.begin(), current_code.end());
-    }
+    buffer_code_.insert(buffer_code_.cend(), current_code.begin(),
+                        current_code.end());
   }
 
  private:
@@ -281,12 +258,13 @@ class Compressor {
   struct TransitionLessThan {
     bool operator()(const Transition &transition_one,
                     const Transition &transition_two) const {
-      if (transition_one.nextstate == transition_two.nextstate)
+      if (transition_one.nextstate == transition_two.nextstate) {
         return transition_one.label < transition_two.label;
-      else
+      } else {
         return transition_one.nextstate < transition_two.nextstate;
+      }
     }
-  } transition_less_than;
+  };
 
   struct TransitionEquals {
     bool operator()(const Transition &transition_one,
@@ -294,17 +272,18 @@ class Compressor {
       return transition_one.nextstate == transition_two.nextstate &&
              transition_one.label == transition_two.label;
     }
-  } transition_equals;
+  };
 
   struct OldDictCompare {
     bool operator()(const std::pair<StateId, Transition> &pair_one,
                     const std::pair<StateId, Transition> &pair_two) const {
-      if ((pair_one.second).nextstate == (pair_two.second).nextstate)
-        return (pair_one.second).label < (pair_two.second).label;
-      else
-        return (pair_one.second).nextstate < (pair_two.second).nextstate;
+      if (pair_one.second.nextstate == pair_two.second.nextstate) {
+        return pair_one.second.label < pair_two.second.label;
+      } else {
+        return pair_one.second.nextstate < pair_two.second.nextstate;
+      }
     }
-  } old_dict_compare;
+  };
 
   std::vector<bool> buffer_code_;
   std::vector<Weight> arc_weight_;
@@ -312,18 +291,16 @@ class Compressor {
 };
 
 template <class Arc>
-inline void Compressor<Arc>::DecodeForCompress(
-    MutableFst<Arc> *fst, const EncodeMapper<Arc> &mapper) {
+void Compressor<Arc>::DecodeForCompress(MutableFst<Arc> *fst,
+                                        const EncodeMapper<Arc> &mapper) {
   ArcMap(fst, EncodeMapper<Arc>(mapper, DECODE));
   fst->SetInputSymbols(mapper.InputSymbols());
   fst->SetOutputSymbols(mapper.OutputSymbols());
 }
 
-// Compressor::BfsOrder
 template <class Arc>
 void Compressor<Arc>::BfsOrder(const ExpandedFst<Arc> &fst,
                                std::vector<StateId> *order) {
-  Arc arc;
   StateId bfs_visit_number = 0;
   std::queue<StateId> states_queue;
   order->assign(fst.NumStates(), kNoStateId);
@@ -332,8 +309,8 @@ void Compressor<Arc>::BfsOrder(const ExpandedFst<Arc> &fst,
   while (!states_queue.empty()) {
     for (ArcIterator<Fst<Arc>> aiter(fst, states_queue.front()); !aiter.Done();
          aiter.Next()) {
-      arc = aiter.Value();
-      StateId nextstate = arc.nextstate;
+      const auto &arc = aiter.Value();
+      const auto nextstate = arc.nextstate;
       if ((*order)[nextstate] == kNoStateId) {
         (*order)[nextstate] = bfs_visit_number++;
         states_queue.push(nextstate);
@@ -341,12 +318,10 @@ void Compressor<Arc>::BfsOrder(const ExpandedFst<Arc> &fst,
     }
     states_queue.pop();
   }
-
-  // If the FST is unconnected, then the following
-  // code finds them
+  // Handles any unconnected states.
   while (bfs_visit_number < fst.NumStates()) {
-    int unseen_state = 0;
-    for (unseen_state = 0; unseen_state < fst.NumStates(); ++unseen_state) {
+    StateId unseen_state = 0;
+    for (; unseen_state < fst.NumStates(); ++unseen_state) {
       if ((*order)[unseen_state] == kNoStateId) break;
     }
     states_queue.push(unseen_state);
@@ -354,8 +329,8 @@ void Compressor<Arc>::BfsOrder(const ExpandedFst<Arc> &fst,
     while (!states_queue.empty()) {
       for (ArcIterator<Fst<Arc>> aiter(fst, states_queue.front());
            !aiter.Done(); aiter.Next()) {
-        arc = aiter.Value();
-        StateId nextstate = arc.nextstate;
+        const auto &arc = aiter.Value();
+        const auto nextstate = arc.nextstate;
         if ((*order)[nextstate] == kNoStateId) {
           (*order)[nextstate] = bfs_visit_number++;
           states_queue.push(nextstate);
@@ -371,15 +346,13 @@ void Compressor<Arc>::Preprocess(const Fst<Arc> &fst,
                                  MutableFst<Arc> *preprocessedfst,
                                  EncodeMapper<Arc> *encoder) {
   *preprocessedfst = fst;
-  if (!preprocessedfst->NumStates()) {
-    return;
-  }
-  // Relabels the edges and develops a dictionary
+  if (!preprocessedfst->NumStates()) return;
+  // Relabels the edges and develops a dictionary.
   Encode(preprocessedfst, encoder);
   std::vector<StateId> order;
-  // Finds the BFS sorting order of the fst
+  // Finds the BFS sorting order of the FST.
   BfsOrder(*preprocessedfst, &order);
-  // Reorders the states according to the BFS order
+  // Reorders the states according to the BFS order.
   StateSort(preprocessedfst, order);
 }
 
@@ -394,29 +367,24 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
   std::vector<std::pair<StateId, LZLabel>> current_new_output;
   std::vector<std::pair<StateId, Transition>> current_old_output;
   std::vector<StateId> final_states;
-
-  StateId number_of_states = fst.NumStates();
-
+  const auto number_of_states = fst.NumStates();
   StateId seen_states = 0;
-  // Adding the number of states
+  // Adds the number of states.
   WriteToBuffer<StateId>(number_of_states);
-
   for (StateId state = 0; state < number_of_states; ++state) {
     current_new_input.clear();
     current_old_input.clear();
     current_new_output.clear();
     current_old_output.clear();
     if (state > seen_states) ++seen_states;
-
-    // Collecting the final states
+    // Collects the final states.
     if (fst.Final(state) != Weight::Zero()) {
       final_states.push_back(state);
       final_weight_.push_back(fst.Final(state));
     }
-
-    // Reading the states
+    // Reads the states.
     for (ArcIterator<Fst<Arc>> aiter(fst, state); !aiter.Done(); aiter.Next()) {
-      Arc arc = aiter.Value();
+      const auto &arc = aiter.Value();
       if (arc.nextstate > seen_states) {  // RILEY: > or >= ?
         ++seen_states;
         LZLabel temp_label;
@@ -431,16 +399,16 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
         current_old_input.push_back(temp_transition);
       }
     }
-    // Adding new states
+    // Adds new states.
     dict_new.BatchEncode(current_new_input, &current_new_output);
     WriteToBuffer<StateId>(current_new_output.size());
-
-    for (auto it = current_new_output.begin(); it != current_new_output.end();
+    for (auto it = current_new_output.cbegin(); it != current_new_output.cend();
          ++it) {
       WriteToBuffer<StateId>(it->first);
       WriteToBuffer<Label>((it->second).label);
     }
-    // Adding old states by sorting and using difference coding
+    // Adds old states by sorting and using difference coding.
+    static const TransitionLessThan transition_less_than;
     std::sort(current_old_input.begin(), current_old_input.end(),
               transition_less_than);
     for (auto it = current_old_input.begin(); it != current_old_input.end();
@@ -464,13 +432,12 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
     std::sort(dict_old_temp.begin(), dict_old_temp.end());
     std::sort(transition_old_temp.begin(), transition_old_temp.end(),
               transition_less_than);
-
     WriteToBuffer<StateId>(dict_old_temp.size());
-    if (dict_old_temp.size() != transition_old_temp.size())
-      WriteToBuffer<int>(1);
-    else
+    if (dict_old_temp.size() == transition_old_temp.size()) {
       WriteToBuffer<int>(0);
-
+    } else {
+      WriteToBuffer<int>(1);
+    }
     StateId previous;
     if (!dict_old_temp.empty()) {
       WriteToBuffer<StateId>(dict_old_temp.front());
@@ -485,8 +452,8 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
     }
     if (!transition_old_temp.empty()) {
       WriteToBuffer<StateId>((transition_old_temp.front()).nextstate);
-      previous = (transition_old_temp.front()).nextstate;
-      WriteToBuffer<Label>((transition_old_temp.front()).label);
+      previous = transition_old_temp.front().nextstate;
+      WriteToBuffer<Label>(transition_old_temp.front().label);
     }
     if (transition_old_temp.size() > 1) {
       for (auto it = transition_old_temp.begin() + 1;
@@ -497,7 +464,7 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
       }
     }
   }
-  // Adding final states
+  // Adds final states.
   WriteToBuffer<StateId>(final_states.size());
   if (!final_states.empty()) {
     for (auto it = final_states.begin(); it != final_states.end(); ++it) {
@@ -505,7 +472,7 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
     }
   }
   WriteToStream(strm);
-  uint8 unweighted = (fst.Properties(kUnweighted, true) == kUnweighted);
+  const uint8 unweighted = fst.Properties(kUnweighted, true) == kUnweighted;
   WriteType(strm, unweighted);
   if (unweighted == 0) {
     WriteWeight(arc_weight_, strm);
@@ -528,8 +495,7 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
   auto arc_weight_it = arc_weight_.begin();
   Transition default_transition;
   StateId seen_states = 1;
-
-  // Adding states.
+  // Adds states..
   const StateId num_states = input.front();
   if (num_states > 0) {
     const StateId start_state = fst->AddState();
@@ -538,17 +504,15 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
       fst->AddState();
     }
   }
-
-  typename std::vector<StateId>::const_iterator main_it = input.begin();
+  auto main_it = input.cbegin();
   ++main_it;
-
   for (StateId current_state = 0; current_state < num_states; ++current_state) {
     if (current_state >= seen_states) ++seen_states;
     current_new_input.clear();
     current_new_output.clear();
     current_old_input.clear();
     current_old_output.clear();
-    // New states
+    // New states.
     StateId current_number_new_elements = *main_it;
     ++main_it;
     for (StateId new_integer = 0; new_integer < current_number_new_elements;
@@ -563,19 +527,17 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
       current_new_input.push_back(temp_new_dict_element);
     }
     dict_new.BatchDecode(current_new_input, &current_new_output);
-    for (auto it = current_new_output.begin(); it != current_new_output.end();
-         ++it) {
+    for (const auto &label : current_new_output) {
       if (!unweighted) {
         fst->AddArc(current_state,
-                    Arc(it->label, it->label, *arc_weight_it, seen_states++));
+                    Arc(label.label, label.label, *arc_weight_it, seen_states));
         ++arc_weight_it;
       } else {
         fst->AddArc(current_state,
-                    Arc(it->label, it->label, Weight::One(), seen_states++));
+                    Arc(label.label, label.label, Weight::One(), seen_states));
       }
+      ++seen_states;
     }
-
-    // Old states dictionary
     StateId current_number_old_elements = *main_it;
     ++main_it;
     StateId is_zero_removed = *main_it;
@@ -596,22 +558,19 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
       Transition temp_test;
       if (!dict_old.SingleDecode(pair_temp_transition.first, &temp_test)) {
         FSTERROR() << "Compressor::Decode: failed";
-        fst->DeleteStates();
         fst->SetProperties(kError, kError);
         return;
       }
       pair_temp_transition.second = temp_test;
       actual_old_dict_numbers.push_back(pair_temp_transition);
     }
-
-    // Reordering the dictionary elements
+    // Reorders the dictionary elements.
+    static const OldDictCompare old_dict_compare;
     std::sort(actual_old_dict_numbers.begin(), actual_old_dict_numbers.end(),
               old_dict_compare);
-
-    // Transitions
+    // Transitions.
     previous = 0;
     actual_old_dict_transitions.clear();
-
     for (StateId new_integer = 0;
          new_integer < current_number_old_elements - is_zero_removed;
          ++new_integer) {
@@ -628,25 +587,24 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
       ++main_it;
       actual_old_dict_transitions.push_back(temp_transition);
     }
-
     if (is_zero_removed == 1) {
       actual_old_dict_transitions.push_back(default_transition);
     }
-
-    auto trans_it = actual_old_dict_transitions.begin();
-    auto dict_it = actual_old_dict_numbers.begin();
-
-    while (trans_it != actual_old_dict_transitions.end() &&
-           dict_it != actual_old_dict_numbers.end()) {
+    auto trans_it = actual_old_dict_transitions.cbegin();
+    auto dict_it = actual_old_dict_numbers.cbegin();
+    while (trans_it != actual_old_dict_transitions.cend() &&
+           dict_it != actual_old_dict_numbers.cend()) {
       if (dict_it->first == 0) {
         ++dict_it;
       } else {
         std::pair<StateId, Transition> temp_pair;
-        if (transition_equals(*trans_it, default_transition) == 1) {
+        static const TransitionEquals transition_equals;
+        static const TransitionLessThan transition_less_than;
+        if (transition_equals(*trans_it, default_transition)) {
           temp_pair.first = dict_it->first;
           temp_pair.second = default_transition;
           ++dict_it;
-        } else if (transition_less_than(dict_it->second, *trans_it) == 1) {
+        } else if (transition_less_than(dict_it->second, *trans_it)) {
           temp_pair.first = dict_it->first;
           temp_pair.second = *trans_it;
           ++dict_it;
@@ -658,23 +616,20 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
         current_old_input.push_back(temp_pair);
       }
     }
-    while (trans_it != actual_old_dict_transitions.end()) {
+    while (trans_it != actual_old_dict_transitions.cend()) {
       std::pair<StateId, Transition> temp_pair;
       temp_pair.first = 0;
       temp_pair.second = *trans_it;
       ++trans_it;
       current_old_input.push_back(temp_pair);
     }
-
-    // Adding old elements in the dictionary
+    // Adds old elements in the dictionary.
     if (!dict_old.BatchDecode(current_old_input, &current_old_output)) {
       FSTERROR() << "Compressor::Decode: Failed";
-      fst->DeleteStates();
       fst->SetProperties(kError, kError);
       return;
     }
-
-    for (auto it = current_old_output.begin(); it != current_old_output.end();
+    for (auto it = current_old_output.cbegin(); it != current_old_output.cend();
          ++it) {
       if (!unweighted) {
         fst->AddArc(current_state,
@@ -686,15 +641,15 @@ void Compressor<Arc>::DecodeProcessedFst(const std::vector<StateId> &input,
       }
     }
   }
-  // Adding the final states
+  // Adds the final states.
   StateId number_of_final_states = *main_it;
   if (number_of_final_states > 0) {
     ++main_it;
     for (StateId temp_int = 0; temp_int < number_of_final_states; ++temp_int) {
-      if (!unweighted) {
-        fst->SetFinal(*main_it, final_weight_[temp_int]);
-      } else {
+      if (unweighted) {
         fst->SetFinal(*main_it, Weight(0));
+      } else {
+        fst->SetFinal(*main_it, final_weight_[temp_int]);
       }
       ++main_it;
     }
@@ -714,7 +669,7 @@ void Compressor<Arc>::ReadWeight(std::istream &strm,
 }
 
 template <class Arc>
-bool Compressor<Arc>::Decompress(std::istream &strm, const string &source,
+bool Compressor<Arc>::Decompress(std::istream &strm, const std::string &source,
                                  MutableFst<Arc> *fst) {
   fst->DeleteStates();
   int32 magic_number = 0;
@@ -743,10 +698,7 @@ bool Compressor<Arc>::Decompress(std::istream &strm, const string &source,
     ReadType(strm, &block);
     for (int j = 0; j < 8; ++j) {
       uint8 temp = msb & block;
-      if (temp == 128)
-        bool_code.push_back(1);
-      else
-        bool_code.push_back(0);
+      bool_code.push_back(temp == 128);
       block = block << 1;
     }
   }
@@ -769,8 +721,7 @@ void Compressor<Arc>::WriteWeight(const std::vector<Weight> &input,
                                   std::ostream &strm) {
   int64 size = input.size();
   WriteType(strm, size);
-  for (typename std::vector<Weight>::const_iterator it = input.begin();
-       it != input.end(); ++it) {
+  for (auto it = input.begin(); it != input.end(); ++it) {
     it->Write(strm);
   }
 }
@@ -780,10 +731,9 @@ void Compressor<Arc>::WriteToStream(std::ostream &strm) {
   while (buffer_code_.size() % 8 != 0) buffer_code_.push_back(1);
   int64 data_size = buffer_code_.size() / 8;
   WriteType(strm, data_size);
-  std::vector<bool>::const_iterator it;
-  int64 i;
+  int64 i = 0;
   uint8 block;
-  for (it = buffer_code_.begin(), i = 0; it != buffer_code_.end(); ++it, ++i) {
+  for (auto it = buffer_code_.begin(); it != buffer_code_.end(); ++it) {
     if (i % 8 == 0) {
       if (i > 0) WriteType(strm, block);
       block = 0;
@@ -791,6 +741,7 @@ void Compressor<Arc>::WriteToStream(std::ostream &strm) {
       block = block << 1;
     }
     block |= *it;
+    ++i;
   }
   WriteType(strm, block);
 }
@@ -801,7 +752,7 @@ bool Compressor<Arc>::Compress(const Fst<Arc> &fst, std::ostream &strm) {
   EncodeMapper<Arc> encoder(kEncodeLabels, ENCODE);
   Preprocess(fst, &processedfst, &encoder);
   WriteType(strm, kCompressMagicNumber);
-  encoder.Write(strm, "encoder stream");
+  encoder.Write(strm, "ostream");
   EncodeProcessedFst(processedfst, strm);
   return true;
 }
@@ -814,89 +765,73 @@ void Compress(const Fst<Arc> &fst, std::ostream &strm) {
   comp.Compress(fst, strm);
 }
 
-// Returns true on success.
 template <class Arc>
-bool Compress(const Fst<Arc> &fst, const string &file_name,
+bool Compress(const Fst<Arc> &fst, const std::string &filename,
               const bool gzip = false) {
   if (gzip) {
-    if (file_name.empty()) {
       std::stringstream strm;
       Compress(fst, strm);
-      OGzFile gzfile(fileno(stdout));
-      gzfile.write(strm);
+      OGzFile gzfile(filename);
       if (!gzfile) {
-        LOG(ERROR) << "Compress: Can't write to file: stdout";
+        LOG(ERROR) << "Compress: Can't open file: "
+                   << (filename.empty() ? "standard output" : filename);
         return false;
       }
-    } else {
-      std::stringstream strm;
-      Compress(fst, strm);
-      OGzFile gzfile(file_name);
+      gzfile.Write(strm);
       if (!gzfile) {
-        LOG(ERROR) << "Compress: Can't open file: " << file_name;
+        LOG(ERROR) << "Compress: Can't write to file: "
+                   << (filename.empty() ? "standard output" : filename);
         return false;
       }
-      gzfile.write(strm);
-      if (!gzfile) {
-        LOG(ERROR) << "Compress: Can't write to file: " << file_name;
-        return false;
-      }
-    }
-  } else if (file_name.empty()) {
-    Compress(fst, std::cout);
-  } else {
-    std::ofstream strm(file_name,
+  } else if (!filename.empty()) {
+    std::ofstream strm(filename,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm) {
-      LOG(ERROR) << "Compress: Can't open file: " << file_name;
+      LOG(ERROR) << "Compress: Can't open file: " << filename;
       return false;
     }
     Compress(fst, strm);
+  } else {
+    Compress(fst, std::cout);
   }
   return true;
 }
 
 template <class Arc>
-void Decompress(std::istream &strm, const string &source,
+bool Decompress(std::istream &strm, const std::string &source,
                 MutableFst<Arc> *fst) {
   Compressor<Arc> comp;
   comp.Decompress(strm, source, fst);
+  return true;
 }
 
 // Returns true on success.
 template <class Arc>
-bool Decompress(const string &file_name, MutableFst<Arc> *fst,
+bool Decompress(const std::string &filename, MutableFst<Arc> *fst,
                 const bool gzip = false) {
   if (gzip) {
-    if (file_name.empty()) {
-      IGzFile gzfile(fileno(stdin));
-      Decompress(*gzfile.read(), "stdin", fst);
-      if (!gzfile) {
-        LOG(ERROR) << "Decompress: Can't read from file: stdin";
-        return false;
-      }
-    } else {
-      IGzFile gzfile(file_name);
-      if (!gzfile) {
-        LOG(ERROR) << "Decompress: Can't open file: " << file_name;
-        return false;
-      }
-      Decompress(*gzfile.read(), file_name, fst);
-      if (!gzfile) {
-        LOG(ERROR) << "Decompress: Can't read from file: " << file_name;
-        return false;
-      }
+    IGzFile gzfile(filename);
+    if (!gzfile) {
+      LOG(ERROR) << "Decompress: Can't open file: "
+                 << (filename.empty() ? "standard input" : filename);
+      return false;
     }
-  } else if (file_name.empty()) {
-    Decompress(std::cin, "stdin", fst);
-  } else {
-    std::ifstream strm(file_name,
+    Decompress(*gzfile.Read(), filename, fst);
+    if (!gzfile) {
+      LOG(ERROR) << "Decompress: Can't read from file: "
+                 << (filename.empty() ? "standard input" : filename);
+      return false;
+    }
+  } else if (!filename.empty()) {
+    std::ifstream strm(filename,
                             std::ios_base::in | std::ios_base::binary);
     if (!strm) {
-      LOG(ERROR) << "Decompress: Can't open file: " << file_name;
+      LOG(ERROR) << "Decompress: Can't open file: " << filename;
       return false;
     }
-    Decompress(strm, file_name, fst);
+    Decompress(strm, filename, fst);
+  } else {
+    Decompress(std::cin, "standard input", fst);
   }
   return true;
 }
diff --git a/src/include/fst/extensions/compress/compressscript.h b/src/include/fst/extensions/compress/compressscript.h
new file mode 100644 (file)
index 0000000..648e94c
--- /dev/null
@@ -0,0 +1,52 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+
+#ifndef FST_EXTENSIONS_COMPRESS_COMPRESSSCRIPT_H_
+#define FST_EXTENSIONS_COMPRESS_COMPRESSSCRIPT_H_
+
+#include <string>
+#include <tuple>
+
+#include <fst/extensions/compress/compress.h>
+#include <fst/script/arg-packs.h>
+#include <fst/script/fst-class.h>
+
+namespace fst {
+namespace script {
+
+using CompressInnerArgs =
+    std::tuple<const FstClass &, const std::string &, const bool>;
+
+using CompressArgs = WithReturnValue<bool, CompressInnerArgs>;
+
+template <class Arc>
+void Compress(CompressArgs *args) {
+  const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
+  const auto &filename = std::get<1>(args->args);
+  const auto gzip = std::get<2>(args->args);
+  args->retval = Compress(fst, filename, gzip);
+}
+
+bool Compress(const FstClass &fst, const std::string &filename,
+              const bool gzip);
+
+using DecompressInnerArgs =
+    std::tuple<const std::string &, MutableFstClass *, const bool>;
+
+using DecompressArgs = WithReturnValue<bool, DecompressInnerArgs>;
+
+template <class Arc>
+void Decompress(DecompressArgs *args) {
+  const auto &filename = std::get<0>(args->args);
+  MutableFst<Arc> *fst = std::get<1>(args->args)->GetMutableFst<Arc>();
+  const auto gzip = std::get<2>(args->args);
+  args->retval = Decompress(filename, fst, gzip);
+}
+
+bool Decompress(const std::string &filename, MutableFstClass *fst,
+                const bool gzip);
+
+}  // namespace script
+}  // namespace fst
+
+#endif  // FST_EXTENSIONS_COMPRESS_COMPRESSSCRIPT_H_
index 6c576d3..acf2ac0 100644 (file)
@@ -15,13 +15,13 @@ namespace fst {
 template <class Var>
 class Elias {
  public:
-  // Gamma encoding is a subroutine for Delta encoding
+  // A subroutine for Delta encoding.
   static void GammaEncode(const Var &input, std::vector<bool> *code);
 
-  // Elias Delta encoding for a single integer
+  // Elias Delta encoding for a single integer.
   static void DeltaEncode(const Var &input, std::vector<bool> *code);
 
-  // Batch decoding of a set of integers
+  // Batch decoding of a set of integers.
   static void BatchDecode(const std::vector<bool> &input,
                           std::vector<Var> *output);
 };
@@ -34,13 +34,13 @@ void Elias<Var>::GammaEncode(const Var &input, std::vector<bool> *code) {
     reverse_code.push(input_copy % 2);
     input_copy = input_copy / 2;
   }
-  for (Var auxvar = 0; auxvar < reverse_code.size() - 1; auxvar++)
-    code->push_back(0);
-  while (reverse_code.empty() != 1) {
+  code->resize(reverse_code.size() - 1, false);
+  while (!reverse_code.empty()) {
     code->push_back(reverse_code.top());
     reverse_code.pop();
   }
 }
+
 template <class Var>
 void Elias<Var>::DeltaEncode(const Var &input, std::vector<bool> *code) {
   Var input_copy = input + 1;
@@ -53,7 +53,7 @@ void Elias<Var>::DeltaEncode(const Var &input, std::vector<bool> *code) {
   }
   GammaEncode(auxvar, code);
   reverse_remainder.pop();
-  while (reverse_remainder.empty() != 1) {
+  while (!reverse_remainder.empty()) {
     code->push_back(reverse_remainder.top());
     reverse_remainder.pop();
   }
@@ -66,27 +66,26 @@ void Elias<Var>::BatchDecode(const std::vector<bool> &input,
   Var remainder_bits = 0;
   Var current_word = 1;
   Var value = 1;
-  std::vector<bool>::const_iterator it = input.begin();
-  while (it != input.end()) {
+  for (auto it = input.cbegin(); it != input.cend();) {
     lead_zeros = 0;
     remainder_bits = 0;
     current_word = 1;
     value = 1;
-    while (*it != 1) {
-      it++;
-      lead_zeros++;
+    while (!*it) {
+      ++it;
+      ++lead_zeros;
     }
-    it++;
+    ++it;
     while (lead_zeros > 0) {
-      lead_zeros--;
+      --lead_zeros;
       current_word = 2 * current_word + *it;
-      it++;
+      ++it;
     }
-    current_word--;
+    --current_word;
     while (current_word > 0) {
       value = 2 * value + *it;
-      current_word--;
-      it++;
+      --current_word;
+      ++it;
     }
     output->push_back(value - 1);
   }
index 2d2e624..a561de1 100644 (file)
 #include <fst/fst.h>
 #include <zlib.h>
 
-using std::stringstream;
-using std::unique_ptr;
-
 namespace fst {
 
 // Gives the zlib gzFile type an OO-like interface. String inputs are all
 // C-style strings. The caller is responsible to get the file modes appropriate
-// for the IO methods being called, and for opening the file descriptors
-// if that constructor is used. The ! operator can be used to check for errors
-// after construction or read/writing.
+// for the IO methods being called. The ! operator can be used to check for
+// errors after construction or read/writing.
 class GzFile {
  public:
   GzFile(const char *filename, const char *mode)
-      : gzfile_(gzopen(filename, mode)), error_(check_handle()) {
-  }
-
-  // The caller is responsible to ensure the corresponding FD is open and has
-  // the needed modes ("r" for reading, "w" or "a" for writing).
-  explicit GzFile(const int fd, const char *mode)
-      : gzfile_(gzdopen(fd, mode)), error_(check_handle()), close_me_(false) {
+      : gzfile_(gzopen(filename, mode)), error_(gzfile_ == nullptr) {
   }
 
-  // If the instance was constructed from an FD, flush the buffer; otherwise,
-  // close the file, which flushes the buffer as a side-effect.
-  ~GzFile() { close_me_ ? gzclose(gzfile_) : gzflush(gzfile_, Z_FINISH); }
+  ~GzFile() { gzclose(gzfile_); }
 
-  inline bool operator!() const { return error_; }
+  bool operator!() const { return error_; }
 
   // Returns false on EOF and sets error if short read does not reach an EOF.
-  int read(void *buf, unsigned int size) {
-    int bytes_read = gzread(gzfile_, buf, size);
+  int Read(void *buf, unsigned int size) {
+    const auto bytes_read = gzread(gzfile_, buf, size);
     if ((bytes_read < size) && !gzeof(gzfile_)) error_ = true;
     return bytes_read;
   }
 
   // Sets error on short writes.
-  void write(const char *buf, unsigned int size) {
+  void Write(const char *buf, unsigned int size) {
     if (gzwrite(gzfile_, buf, size) != size) error_ = true;
   }
 
  private:
-  // gzopen and gzdopen signal failure by returning null.
-  bool check_handle() { return gzfile_ == nullptr; }
-
-  gzFile gzfile_ = nullptr;
-  bool error_ = false;
+  gzFile gzfile_;
+  bool error_;
   bool close_me_ = false;
 };
 
 // Resource handle for writing stringstream to GzFile.
 class OGzFile {
  public:
-  explicit OGzFile(const string &filename) : OGzFile(filename.c_str()) {}
-
-  explicit OGzFile(const char *filename) : gz_(GzFile(filename, mode_)) {}
+  explicit OGzFile(const std::string &filename) : OGzFile(filename.c_str()) {}
 
-  explicit OGzFile(const int fd) : gz_(GzFile(fd, mode_)) {}
+  explicit OGzFile(const char *filename) : gz_(GzFile(filename, "wb")) {}
 
   inline bool operator!() const { return !gz_; }
 
-  void write(const std::stringstream &ssbuf) {
-    string sbuf = ssbuf.str();
-    gz_.write(sbuf.data(), sbuf.size());
+  void Write(const std::stringstream &ssbuf) {
+    const auto sbuf = ssbuf.str();
+    gz_.Write(sbuf.data(), sbuf.size());
   }
 
  private:
   GzFile gz_;
-  static constexpr auto &mode_ = "wb";
 };
 
 // Resource handle for reading stringstream from GzFile.
 class IGzFile {
  public:
-  explicit IGzFile(const string &filename) : IGzFile(filename.c_str()) {}
-
-  explicit IGzFile(const char *filename) : gz_(GzFile(filename, mode_)) {}
+  explicit IGzFile(const std::string &filename) : IGzFile(filename.c_str()) {}
 
-  explicit IGzFile(const int fd) : gz_(GzFile(fd, mode_)) {}
+  explicit IGzFile(const char *filename) : gz_(GzFile(filename, "rb")) {}
 
   inline bool operator!() const { return !gz_; }
 
   // This is a great case for "move", but GCC 4 is missing the C+11 standard
   // move constructor for stringstream, so a unique_ptr is the next best thing.
-  std::unique_ptr<std::stringstream> read() {
+  std::unique_ptr<std::stringstream> Read() {
     char buf[bufsize_];
     std::unique_ptr<std::stringstream> sstrm(new std::stringstream);
     // We always read at least once, and the result of the last read is always
     // pushed onto the stringstream. We use the "write" member because << onto
     // a stringstream stops at the null byte, which might be data!
     int bytes_read;
-    while ((bytes_read = gz_.read(buf, bufsize_)) == bufsize_)
+    while ((bytes_read = gz_.Read(buf, bufsize_)) == bufsize_) {
       sstrm->write(buf, bufsize_);
+    }
     sstrm->write(buf, bytes_read);
     return sstrm;
   }
 
  private:
   GzFile gz_;
-  static constexpr auto &mode_ = "rb";
   // This is the same size as the default internal buffer for zlib.
   static const size_t bufsize_ = 8192;
 };
diff --git a/src/include/fst/extensions/compress/randmod.h b/src/include/fst/extensions/compress/randmod.h
deleted file mode 100644 (file)
index bfe2de5..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Generates a random FST according to a class-specific transition model.
-
-#ifndef FST_EXTENSIONS_COMPRESS_RANDMOD_H_
-#define FST_EXTENSIONS_COMPRESS_RANDMOD_H_
-
-#include <cstdlib>
-#include <vector>
-
-#include <fst/compat.h>
-#include <fst/mutable-fst.h>
-
-namespace fst {
-
-template <class Arc, class G>
-class RandMod {
- public:
-  typedef typename Arc::StateId StateId;
-  typedef typename Arc::Label Label;
-  typedef typename Arc::Weight Weight;
-
-  // Generates random FST with 'nstates' with 'nclasses' in the probability
-  // generation model, and 'nlabels' in the alphabet. If 'trans' = true, then
-  // a transducer is generated; iff 'generate_' is non-null, the output is
-  // randomly weighted.
-  RandMod(StateId nstates, StateId nclasses, Label nlabels, bool trans,
-          const G *generate)
-      : nstates_(nstates),
-        nclasses_(nclasses),
-        nlabels_(nlabels),
-        trans_(trans),
-        generate_(generate) {
-    for (StateId s = 0; s < nstates; ++s) {
-      classes_.push_back(rand() % nclasses);  // NOLINT
-    }
-  }
-
-  // Generates a random FST according to a class-specific transition model
-  void Generate(StdMutableFst *fst) {
-    StateId start = rand() % nstates_;  // NOLINT
-    fst->DeleteStates();
-    for (StateId s = 0; s < nstates_; ++s) {
-      fst->AddState();
-      if (s == start) fst->SetStart(start);
-      for (StateId n = 0; n <= nstates_; ++n) {
-        Arc arc;
-        StateId d = n == nstates_ ? kNoStateId : n;
-        if (!RandArc(s, d, &arc)) continue;
-        if (d == kNoStateId) {  // A super-final transition?
-          fst->SetFinal(s, arc.weight);
-        } else {
-          fst->AddArc(s, arc);
-        }
-      }
-    }
-  }
-
- private:
-  // Generates a transition from s to d. If d == kNoStateId, a superfinal
-  // transition is generated. Returns false if no transition generated.
-  bool RandArc(StateId s, StateId d, Arc *arc) {
-    StateId sclass = classes_[s];
-    StateId dclass = d != kNoStateId ? classes_[d] : 0;
-
-    int r = sclass + dclass + 2;
-    if ((rand() % r) != 0)  // NOLINT
-      return false;
-
-    arc->nextstate = d;
-
-    Label ilabel = kNoLabel;
-    Label olabel = kNoLabel;
-    if (d != kNoStateId) {
-      ilabel = (dclass % nlabels_) + 1;
-      if (trans_)
-        olabel = (sclass % nlabels_) + 1;
-      else
-        olabel = ilabel;
-    }
-
-    Weight weight = Weight::One();
-    if (generate_) weight = (*generate_)();
-
-    arc->ilabel = ilabel;
-    arc->olabel = olabel;
-    arc->weight = weight;
-    return true;
-  }
-
-  StateId nstates_;
-  StateId nclasses_;
-  Label nlabels_;
-  bool trans_;
-  const G *generate_;
-  std::vector<StateId> classes_;
-};
-
-}  // namespace fst
-
-#endif  // FST_EXTENSIONS_COMPRESS_RANDMOD_H_
index 09c3f69..599dda3 100644 (file)
@@ -34,9 +34,9 @@ class StringReader {
 
   enum EntryType { LINE = 1, FILE = 2 };
 
-  StringReader(std::istream &istrm, const string &source, EntryType entry_type,
-               StringTokenType token_type, bool allow_negative_labels,
-               const SymbolTable *syms = nullptr,
+  StringReader(std::istream &istrm, const std::string &source,
+               EntryType entry_type, StringTokenType token_type,
+               bool allow_negative_labels, const SymbolTable *syms = nullptr,
                Label unknown_label = kNoStateId)
       : nline_(0),
         istrm_(istrm),
@@ -62,7 +62,7 @@ class StringReader {
       ++nline_;
     } else {
       content_.clear();
-      string line;
+      std::string line;
       while (getline(istrm_, line)) {
         ++nline_;
         content_.append(line);
@@ -106,31 +106,32 @@ class StringReader {
  private:
   size_t nline_;
   std::istream &istrm_;
-  string source_;
+  std::string source_;
   EntryType entry_type_;
   StringTokenType token_type_;
   const SymbolTable *symbols_;
   bool done_;
   StringCompiler<Arc> compiler_;
-  string content_;  // The actual content of the input stream's next FST.
+  std::string content_;  // The actual content of the input stream's next FST.
 
   StringReader(const StringReader &) = delete;
   StringReader &operator=(const StringReader &) = delete;
 };
 
 // Computes the minimal length required to encode each line number as a decimal
-// number.
+// number, or zero if the file is not seekable.
 int KeySize(const char *filename);
 
 template <class Arc>
-void FarCompileStrings(const std::vector<string> &in_fnames,
-                       const string &out_fname, const string &fst_type,
-                       const FarType &far_type, int32 generate_keys,
-                       FarEntryType fet, FarTokenType tt,
-                       const string &symbols_fname,
-                       const string &unknown_symbol, bool keep_symbols,
+void FarCompileStrings(const std::vector<std::string> &in_fnames,
+                       const std::string &out_fname,
+                       const std::string &fst_type, const FarType &far_type,
+                       int32 generate_keys, FarEntryType fet, FarTokenType tt,
+                       const std::string &symbols_fname,
+                       const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
-                       const string &key_prefix, const string &key_suffix) {
+                       const std::string &key_prefix,
+                       const std::string &key_suffix) {
   typename StringReader<Arc>::EntryType entry_type;
   if (fet == FET_LINE) {
     entry_type = StringReader<Arc>::LINE;
@@ -184,14 +185,20 @@ void FarCompileStrings(const std::vector<string> &in_fnames,
   if (!far_writer) return;
   int n = 0;
   for (const auto &in_fname : in_fnames) {
+    // Don't try to call KeySize("").
     if (generate_keys == 0 && in_fname.empty()) {
       FSTERROR() << "FarCompileStrings: Read from a file instead of stdin or"
-                 << " set the --generate_keys flags.";
+                 << " set the --generate_keys flag.";
       return;
     }
-    int key_size =
+    const int key_size =
         generate_keys ? generate_keys : (entry_type == StringReader<Arc>::FILE
                                              ? 1 : KeySize(in_fname.c_str()));
+    if (key_size == 0) {
+      FSTERROR() << "FarCompileStrings: " << in_fname << " is not seekable.  "
+                 << "Read from a file instead or set the --generate_keys flag.";
+      return;
+    }
     std::ifstream fstrm;
     if (!in_fname.empty()) {
       fstrm.open(in_fname);
@@ -232,7 +239,7 @@ void FarCompileStrings(const std::vector<string> &in_fnames,
       keybuf.width(key_size);
       keybuf.fill('0');
       keybuf << n;
-      string key;
+      std::string key;
       if (generate_keys > 0) {
         key = keybuf.str();
       } else {
index 9b384b1..26708fe 100644 (file)
 namespace fst {
 
 template <class Arc>
-void FarCreate(const std::vector<string> &in_fnames, const string &out_fname,
-               const int32 generate_keys, const FarType &far_type,
-               const string &key_prefix, const string &key_suffix) {
+void FarCreate(const std::vector<std::string> &in_fnames,
+               const std::string &out_fname, const int32 generate_keys,
+               const FarType &far_type, const std::string &key_prefix,
+               const std::string &key_suffix) {
   std::unique_ptr<FarWriter<Arc>> far_writer(
       FarWriter<Arc>::Create(out_fname, far_type));
   if (!far_writer) return;
   for (size_t i = 0; i < in_fnames.size(); ++i) {
     std::unique_ptr<Fst<Arc>> ifst(Fst<Arc>::Read(in_fnames[i]));
     if (!ifst) return;
-    string key;
+    std::string key;
     if (generate_keys > 0) {
       std::ostringstream keybuf;
       keybuf.width(generate_keys);
index 04511d2..86eb84c 100644 (file)
 namespace fst {
 
 template <class Arc>
-bool FarEqual(const string &filename1, const string &filename2,
-              float delta = kDelta, const string &begin_key = string(),
-              const string &end_key = string()) {
+bool FarEqual(const std::string &filename1, const std::string &filename2,
+              float delta = kDelta,
+              const std::string &begin_key = std::string(),
+              const std::string &end_key = std::string()) {
   std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(filename1));
   if (!reader1) {
     LOG(ERROR) << "FarEqual: Could not open FAR file " << filename1;
index e707835..ffa645b 100644 (file)
 namespace fst {
 
 template <class Arc>
-inline void FarWriteFst(const Fst<Arc> *fst, string key, string *okey,
+inline void FarWriteFst(const Fst<Arc> *fst, std::string key, std::string *okey,
                         int *nrep, int32 generate_filenames, int i,
-                        const string &filename_prefix,
-                        const string &filename_suffix) {
+                        const std::string &filename_prefix,
+                        const std::string &filename_suffix) {
   if (key == *okey) {
     ++*nrep;
   } else {
     *nrep = 0;
   }
   *okey = key;
-  string ofilename;
+  std::string ofilename;
   if (generate_filenames) {
     std::ostringstream tmp;
     tmp.width(generate_filenames);
@@ -45,14 +45,16 @@ inline void FarWriteFst(const Fst<Arc> *fst, string key, string *okey,
 }
 
 template <class Arc>
-void FarExtract(const std::vector<string> &ifilenames, int32 generate_filenames,
-                const string &keys, const string &key_separator,
-                const string &range_delimiter, const string &filename_prefix,
-                const string &filename_suffix) {
+void FarExtract(const std::vector<std::string> &ifilenames,
+                int32 generate_filenames, const std::string &keys,
+                const std::string &key_separator,
+                const std::string &range_delimiter,
+                const std::string &filename_prefix,
+                const std::string &filename_suffix) {
   std::unique_ptr<FarReader<Arc>> far_reader(
       FarReader<Arc>::Open(ifilenames));
   if (!far_reader) return;
-  string okey;
+  std::string okey;
   int nrep = 0;
   std::vector<char *> key_vector;
   // User has specified a set of FSTs to extract, where some of these may in
@@ -63,7 +65,7 @@ void FarExtract(const std::vector<string> &ifilenames, int32 generate_filenames,
     SplitString(keys_cstr, key_separator.c_str(), &key_vector, true);
     int i = 0;
     for (size_t k = 0; k < key_vector.size(); ++k, ++i) {
-      string key = key_vector[k];
+      std::string key = key_vector[k];
       auto *key_cstr = new char[key.size() + 1];
       strcpy(key_cstr, key.c_str());
       std::vector<char *> range_vector;
@@ -77,8 +79,8 @@ void FarExtract(const std::vector<string> &ifilenames, int32 generate_filenames,
         FarWriteFst(fst, key, &okey, &nrep, generate_filenames, i,
                     filename_prefix, filename_suffix);
       } else if (range_vector.size() == 2) {  // A legal range
-        string begin_key = range_vector[0];
-        string end_key = range_vector[1];
+        std::string begin_key = range_vector[0];
+        std::string end_key = range_vector[1];
         if (begin_key.empty() || end_key.empty()) {
           LOG(ERROR) << "FarExtract: Illegal range specification " << key;
           return;
@@ -110,7 +112,6 @@ void FarExtract(const std::vector<string> &ifilenames, int32 generate_filenames,
     FarWriteFst(fst, key, &okey, &nrep, generate_filenames, i, filename_prefix,
                 filename_suffix);
   }
-  return;
 }
 
 }  // namespace fst
index 50d7be9..57a0ec7 100644 (file)
@@ -24,12 +24,12 @@ namespace script {
 // See the FarReader interface in far.h for the exact semantics.
 class FarReaderImplBase {
  public:
-  virtual const string &ArcType() const = 0;
+  virtual const std::string &ArcType() const = 0;
   virtual bool Done() const = 0;
   virtual bool Error() const = 0;
-  virtual const string &GetKey() const = 0;
+  virtual const std::string &GetKey() const = 0;
   virtual const FstClass *GetFstClass() const = 0;
-  virtual bool Find(const string &key) = 0;
+  virtual bool Find(const std::string &key) = 0;
   virtual void Next() = 0;
   virtual void Reset() = 0;
   virtual FarType Type() const = 0;
@@ -40,26 +40,26 @@ class FarReaderImplBase {
 template <class Arc>
 class FarReaderClassImpl : public FarReaderImplBase {
  public:
-  explicit FarReaderClassImpl(const string &filename)
+  explicit FarReaderClassImpl(const std::string &filename)
       : impl_(FarReader<Arc>::Open(filename)) {}
 
-  explicit FarReaderClassImpl(const std::vector<string> &filenames)
+  explicit FarReaderClassImpl(const std::vector<std::string> &filenames)
       : impl_(FarReader<Arc>::Open(filenames)) {}
 
-  const string &ArcType() const final { return Arc::Type(); }
+  const std::string &ArcType() const final { return Arc::Type(); }
 
   bool Done() const final { return impl_->Done(); }
 
   bool Error() const final { return impl_->Error(); }
 
-  bool Find(const string &key) final { return impl_->Find(key); }
+  bool Find(const std::string &key) final { return impl_->Find(key); }
 
   const FstClass *GetFstClass() const final {
     fstc_.reset(new FstClass(*impl_->GetFst()));
     return fstc_.get();
   }
 
-  const string &GetKey() const final { return impl_->GetKey(); }
+  const std::string &GetKey() const final { return impl_->GetKey(); }
 
   void Next() final { return impl_->Next(); }
 
@@ -80,12 +80,12 @@ class FarReaderClassImpl : public FarReaderImplBase {
 class FarReaderClass;
 
 using OpenFarReaderClassArgs =
-    WithReturnValue<FarReaderClass *, const std::vector<string> &>;
+    WithReturnValue<FarReaderClass *, const std::vector<std::string> &>;
 
 // Untemplated user-facing class holding a templated pimpl.
 class FarReaderClass {
  public:
-  const string &ArcType() const { return impl_->ArcType(); }
+  const std::string &ArcType() const { return impl_->ArcType(); }
 
   bool Done() const { return impl_->Done(); }
 
@@ -93,11 +93,11 @@ class FarReaderClass {
   // Attempting to call any other function will result in null dereference.
   bool Error() const { return (impl_) ? impl_->Error() : true; }
 
-  bool Find(const string &key) { return impl_->Find(key); }
+  bool Find(const std::string &key) { return impl_->Find(key); }
 
   const FstClass *GetFstClass() const { return impl_->GetFstClass(); }
 
-  const string &GetKey() const { return impl_->GetKey(); }
+  const std::string &GetKey() const { return impl_->GetKey(); }
 
   void Next() { impl_->Next(); }
 
@@ -126,9 +126,9 @@ class FarReaderClass {
 
   // Defined in the CC.
 
-  static FarReaderClass *Open(const string &filename);
+  static FarReaderClass *Open(const std::string &filename);
 
-  static FarReaderClass *Open(const std::vector<string> &filenames);
+  static FarReaderClass *Open(const std::vector<std::string> &filenames);
 
  private:
   template <class Arc>
@@ -152,8 +152,8 @@ class FarWriterImplBase {
  public:
   // Unlike the lower-level library, this returns a boolean to signal failure
   // due to non-conformant arc types.
-  virtual bool Add(const string &key, const FstClass &fst) = 0;
-  virtual const string &ArcType() const = 0;
+  virtual bool Add(const std::string &key, const FstClass &fst) = 0;
+  virtual const std::string &ArcType() const = 0;
   virtual bool Error() const = 0;
   virtual FarType Type() const = 0;
   virtual ~FarWriterImplBase() {}
@@ -164,11 +164,11 @@ class FarWriterImplBase {
 template <class Arc>
 class FarWriterClassImpl : public FarWriterImplBase {
  public:
-  explicit FarWriterClassImpl(const string &filename,
+  explicit FarWriterClassImpl(const std::string &filename,
                               FarType type = FAR_DEFAULT)
       : impl_(FarWriter<Arc>::Create(filename, type)) {}
 
-  bool Add(const string &key, const FstClass &fst) final {
+  bool Add(const std::string &key, const FstClass &fst) final {
     if (ArcType() != fst.ArcType()) {
       FSTERROR() << "Cannot write FST with " << fst.ArcType() << " arcs to "
                  << "FAR with " << ArcType() << " arcs";
@@ -178,7 +178,7 @@ class FarWriterClassImpl : public FarWriterImplBase {
     return true;
   }
 
-  const string &ArcType() const final { return Arc::Type(); }
+  const std::string &ArcType() const final { return Arc::Type(); }
 
   bool Error() const final { return impl_->Error(); }
 
@@ -195,7 +195,7 @@ class FarWriterClassImpl : public FarWriterImplBase {
 
 class FarWriterClass;
 
-using CreateFarWriterClassInnerArgs = std::pair<const string &, FarType>;
+using CreateFarWriterClassInnerArgs = std::pair<const std::string &, FarType>;
 
 using CreateFarWriterClassArgs =
     WithReturnValue<FarWriterClass *, CreateFarWriterClassInnerArgs>;
@@ -203,10 +203,11 @@ using CreateFarWriterClassArgs =
 // Untemplated user-facing class holding a templated pimpl.
 class FarWriterClass {
  public:
-  static FarWriterClass *Create(const string &filename, const string &arc_type,
+  static FarWriterClass *Create(const std::string &filename,
+                                const std::string &arc_type,
                                 FarType type = FAR_DEFAULT);
 
-  bool Add(const string &key, const FstClass &fst) {
+  bool Add(const std::string &key, const FstClass &fst) {
     return impl_->Add(key, fst);
   }
 
@@ -214,7 +215,7 @@ class FarWriterClass {
   // Attempting to call any other function will result in null dereference.
   bool Error() const { return (impl_) ? impl_->Error() : true; }
 
-  const string &ArcType() const { return impl_->ArcType(); }
+  const std::string &ArcType() const { return impl_->ArcType(); }
 
   FarType Type() const { return impl_->Type(); }
 
index c24c7da..0cd01a9 100644 (file)
@@ -12,9 +12,9 @@
 #include <fst/log.h>
 #include <fst/extensions/far/stlist.h>
 #include <fst/extensions/far/sttable.h>
+#include <fstream>
 #include <fst/fst.h>
 #include <fst/vector-fst.h>
-#include <fstream>
 
 namespace fst {
 
@@ -22,7 +22,7 @@ enum FarEntryType { FET_LINE, FET_FILE };
 
 enum FarTokenType { FTT_SYMBOL, FTT_BYTE, FTT_UTF8 };
 
-inline bool IsFst(const string &filename) {
+inline bool IsFst(const std::string &filename) {
   std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
   return IsFstHeader(strm, filename);
@@ -31,11 +31,11 @@ inline bool IsFst(const string &filename) {
 // FST archive header class
 class FarHeader {
  public:
-  const string &ArcType() const { return arctype_; }
+  const std::string &ArcType() const { return arctype_; }
 
-  const string &FarType() const { return fartype_; }
+  const std::string &FarType() const { return fartype_; }
 
-  bool Read(const string &filename) {
+  bool Read(const std::string &filename) {
     FstHeader fsthdr;
     if (filename.empty()) {
       // Header reading unsupported on stdin. Assumes STList and StdArc.
@@ -64,8 +64,8 @@ class FarHeader {
   }
 
  private:
-  string fartype_;
-  string arctype_;
+  std::string fartype_;
+  std::string arctype_;
 };
 
 enum FarType {
@@ -82,11 +82,12 @@ class FarWriter {
   using Arc = A;
 
   // Creates a new (empty) FST archive; returns null on error.
-  static FarWriter *Create(const string &filename, FarType type = FAR_DEFAULT);
+  static FarWriter *Create(const std::string &filename,
+                           FarType type = FAR_DEFAULT);
 
   // Adds an FST to the end of an archive. Keys must be non-empty and
   // in lexicographic order. FSTs must have a suitable write method.
-  virtual void Add(const string &key, const Fst<Arc> &fst) = 0;
+  virtual void Add(const std::string &key, const Fst<Arc> &fst) = 0;
 
   virtual FarType Type() const = 0;
 
@@ -106,17 +107,17 @@ class FarReader {
 
   // Opens an existing FST archive in a single file; returns null on error.
   // Sets current position to the beginning of the achive.
-  static FarReader *Open(const string &filename);
+  static FarReader *Open(const std::string &filename);
 
   // Opens an existing FST archive in multiple files; returns null on error.
   // Sets current position to the beginning of the achive.
-  static FarReader *Open(const std::vector<string> &filenames);
+  static FarReader *Open(const std::vector<std::string> &filenames);
 
   // Resets current position to beginning of archive.
   virtual void Reset() = 0;
 
   // Sets current position to first entry >= key.  Returns true if a match.
-  virtual bool Find(const string &key) = 0;
+  virtual bool Find(const std::string &key) = 0;
 
   // Current position at end of archive?
   virtual bool Done() const = 0;
@@ -126,7 +127,7 @@ class FarReader {
 
   // Returns key at the current position. This reference is invalidated if
   // the current position in the archive is changed.
-  virtual const string &GetKey() const = 0;
+  virtual const std::string &GetKey() const = 0;
 
   // Returns pointer to FST at the current position. This is invalidated if
   // the current position in the archive is changed.
@@ -155,12 +156,12 @@ class STTableFarWriter : public FarWriter<A> {
  public:
   using Arc = A;
 
-  static STTableFarWriter *Create(const string &filename) {
+  static STTableFarWriter *Create(const std::string &filename) {
     auto *writer = STTableWriter<Fst<Arc>, FstWriter<Arc>>::Create(filename);
     return new STTableFarWriter(writer);
   }
 
-  void Add(const string &key, const Fst<Arc> &fst) final {
+  void Add(const std::string &key, const Fst<Arc> &fst) final {
     writer_->Add(key, fst);
   }
 
@@ -180,12 +181,12 @@ class STListFarWriter : public FarWriter<A> {
  public:
   using Arc = A;
 
-  static STListFarWriter *Create(const string &filename) {
+  static STListFarWriter *Create(const std::string &filename) {
     auto *writer = STListWriter<Fst<Arc>, FstWriter<Arc>>::Create(filename);
     return new STListFarWriter(writer);
   }
 
-  void Add(const string &key, const Fst<Arc> &fst) final {
+  void Add(const std::string &key, const Fst<Arc> &fst) final {
     writer_->Add(key, fst);
   }
 
@@ -205,14 +206,14 @@ class FstFarWriter : public FarWriter<A> {
  public:
   using Arc = A;
 
-  explicit FstFarWriter(const string &filename)
+  explicit FstFarWriter(const std::string &filename)
       : filename_(filename), error_(false), written_(false) {}
 
-  static FstFarWriter *Create(const string &filename) {
+  static FstFarWriter *Create(const std::string &filename) {
     return new FstFarWriter(filename);
   }
 
-  void Add(const string &key, const Fst<A> &fst) final {
+  void Add(const std::string &key, const Fst<A> &fst) final {
     if (written_) {
       LOG(WARNING) << "FstFarWriter::Add: only one FST supported,"
                    << " subsequent entries discarded.";
@@ -229,13 +230,14 @@ class FstFarWriter : public FarWriter<A> {
   ~FstFarWriter() final {}
 
  private:
-  string filename_;
+  std::string filename_;
   bool error_;
   bool written_;
 };
 
 template <class Arc>
-FarWriter<Arc> *FarWriter<Arc>::Create(const string &filename, FarType type) {
+FarWriter<Arc> *FarWriter<Arc>::Create(const std::string &filename,
+                                       FarType type) {
   switch (type) {
     case FAR_DEFAULT:
       if (filename.empty()) return STListFarWriter<Arc>::Create(filename);
@@ -254,8 +256,9 @@ FarWriter<Arc> *FarWriter<Arc>::Create(const string &filename, FarType type) {
 template <class Arc>
 class FstReader {
  public:
-  Fst<Arc> *operator()(std::istream &strm) const {
-    return Fst<Arc>::Read(strm, FstReadOptions());
+  Fst<Arc> *operator()(std::istream &strm,
+                       const FstReadOptions &options = FstReadOptions()) const {
+    return Fst<Arc>::Read(strm, options);
   }
 };
 
@@ -264,13 +267,13 @@ class STTableFarReader : public FarReader<A> {
  public:
   using Arc = A;
 
-  static STTableFarReader *Open(const string &filename) {
+  static STTableFarReader *Open(const std::string &filename) {
     auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(filename);
     if (!reader || reader->Error()) return nullptr;
     return new STTableFarReader(reader);
   }
 
-  static STTableFarReader *Open(const std::vector<string> &filenames) {
+  static STTableFarReader *Open(const std::vector<std::string> &filenames) {
     auto *reader = STTableReader<Fst<Arc>, FstReader<Arc>>::Open(filenames);
     if (!reader || reader->Error()) return nullptr;
     return new STTableFarReader(reader);
@@ -278,13 +281,13 @@ class STTableFarReader : public FarReader<A> {
 
   void Reset() final { reader_->Reset(); }
 
-  bool Find(const string &key) final { return reader_->Find(key); }
+  bool Find(const std::string &key) final { return reader_->Find(key); }
 
   bool Done() const final { return reader_->Done(); }
 
   void Next() final { return reader_->Next(); }
 
-  const string &GetKey() const final { return reader_->GetKey(); }
+  const std::string &GetKey() const final { return reader_->GetKey(); }
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
@@ -304,13 +307,13 @@ class STListFarReader : public FarReader<A> {
  public:
   using Arc = A;
 
-  static STListFarReader *Open(const string &filename) {
+  static STListFarReader *Open(const std::string &filename) {
     auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(filename);
     if (!reader || reader->Error()) return nullptr;
     return new STListFarReader(reader);
   }
 
-  static STListFarReader *Open(const std::vector<string> &filenames) {
+  static STListFarReader *Open(const std::vector<std::string> &filenames) {
     auto *reader = STListReader<Fst<Arc>, FstReader<Arc>>::Open(filenames);
     if (!reader || reader->Error()) return nullptr;
     return new STListFarReader(reader);
@@ -318,13 +321,13 @@ class STListFarReader : public FarReader<A> {
 
   void Reset() final { reader_->Reset(); }
 
-  bool Find(const string &key) final { return reader_->Find(key); }
+  bool Find(const std::string &key) final { return reader_->Find(key); }
 
   bool Done() const final { return reader_->Done(); }
 
   void Next() final { return reader_->Next(); }
 
-  const string &GetKey() const final { return reader_->GetKey(); }
+  const std::string &GetKey() const final { return reader_->GetKey(); }
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
@@ -344,17 +347,17 @@ class FstFarReader : public FarReader<A> {
  public:
   using Arc = A;
 
-  static FstFarReader *Open(const string &filename) {
-    std::vector<string> filenames;
+  static FstFarReader *Open(const std::string &filename) {
+    std::vector<std::string> filenames;
     filenames.push_back(filename);
     return new FstFarReader<Arc>(filenames);
   }
 
-  static FstFarReader *Open(const std::vector<string> &filenames) {
+  static FstFarReader *Open(const std::vector<std::string> &filenames) {
     return new FstFarReader<Arc>(filenames);
   }
 
-  explicit FstFarReader(const std::vector<string> &filenames)
+  explicit FstFarReader(const std::vector<std::string> &filenames)
       : keys_(filenames), has_stdin_(false), pos_(0), error_(false) {
     std::sort(keys_.begin(), keys_.end());
     streams_.resize(keys_.size(), 0);
@@ -395,7 +398,7 @@ class FstFarReader : public FarReader<A> {
     ReadFst();
   }
 
-  bool Find(const string &key) final {
+  bool Find(const std::string &key) final {
     if (has_stdin_) {
       FSTERROR()
           << "FstFarReader::Find: Operation not supported on standard input";
@@ -414,7 +417,7 @@ class FstFarReader : public FarReader<A> {
     ReadFst();
   }
 
-  const string &GetKey() const final { return keys_[pos_]; }
+  const std::string &GetKey() const final { return keys_[pos_]; }
 
   const Fst<Arc> *GetFst() const final { return fst_.get(); }
 
@@ -442,7 +445,7 @@ class FstFarReader : public FarReader<A> {
     }
   }
 
-  std::vector<string> keys_;
+  std::vector<std::string> keys_;
   std::vector<std::istream *> streams_;
   bool has_stdin_;
   size_t pos_;
@@ -451,7 +454,7 @@ class FstFarReader : public FarReader<A> {
 };
 
 template <class Arc>
-FarReader<Arc> *FarReader<Arc>::Open(const string &filename) {
+FarReader<Arc> *FarReader<Arc>::Open(const std::string &filename) {
   if (filename.empty())
     return STListFarReader<Arc>::Open(filename);
   else if (IsSTTable(filename))
@@ -464,7 +467,8 @@ FarReader<Arc> *FarReader<Arc>::Open(const string &filename) {
 }
 
 template <class Arc>
-FarReader<Arc> *FarReader<Arc>::Open(const std::vector<string> &filenames) {
+FarReader<Arc> *FarReader<Arc>::Open(
+    const std::vector<std::string> &filenames) {
   if (!filenames.empty() && filenames[0].empty())
     return STListFarReader<Arc>::Open(filenames);
   else if (!filenames.empty() && IsSTTable(filenames[0]))
index 4bd11a9..b54c42f 100644 (file)
@@ -30,29 +30,30 @@ namespace script {
 // 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!
 struct FarCompileStringsArgs {
-  const std::vector<string> &in_fnames;
-  const string &out_fname;
-  const string &fst_type;
+  const std::vector<std::string> &in_fnames;
+  const std::string &out_fname;
+  const std::string &fst_type;
   const FarType &far_type;
   const int32 generate_keys;
   const FarEntryType fet;
   const FarTokenType tt;
-  const string &symbols_fname;
-  const string &unknown_symbol;
+  const std::string &symbols_fname;
+  const std::string &unknown_symbol;
   const bool keep_symbols;
   const bool initial_symbols;
   const bool allow_negative_labels;
-  const string &key_prefix;
-  const string &key_suffix;
-
-  FarCompileStringsArgs(const std::vector<string> &in_fnames,
-                        const string &out_fname, const string &fst_type,
-                        const FarType &far_type, int32 generate_keys,
-                        FarEntryType fet, FarTokenType tt,
-                        const string &symbols_fname,
-                        const string &unknown_symbol, bool keep_symbols,
+  const std::string &key_prefix;
+  const std::string &key_suffix;
+
+  FarCompileStringsArgs(const std::vector<std::string> &in_fnames,
+                        const std::string &out_fname,
+                        const std::string &fst_type, const FarType &far_type,
+                        int32 generate_keys, FarEntryType fet, FarTokenType tt,
+                        const std::string &symbols_fname,
+                        const std::string &unknown_symbol, bool keep_symbols,
                         bool initial_symbols, bool allow_negative_labels,
-                        const string &key_prefix, const string &key_suffix)
+                        const std::string &key_prefix,
+                        const std::string &key_suffix)
       : in_fnames(in_fnames),
         out_fname(out_fname),
         fst_type(fst_type),
@@ -78,29 +79,32 @@ void FarCompileStrings(FarCompileStringsArgs *args) {
       args->allow_negative_labels, args->key_prefix, args->key_suffix);
 }
 
-void FarCompileStrings(const std::vector<string> &in_fnames,
-                       const string &out_fname, const string &arc_type,
-                       const string &fst_type, const FarType &far_type,
-                       int32 generate_keys, FarEntryType fet, FarTokenType tt,
-                       const string &symbols_fname,
-                       const string &unknown_symbol, bool keep_symbols,
+void FarCompileStrings(const std::vector<std::string> &in_fnames,
+                       const std::string &out_fname,
+                       const std::string &arc_type, const std::string &fst_type,
+                       const FarType &far_type, int32 generate_keys,
+                       FarEntryType fet, FarTokenType tt,
+                       const std::string &symbols_fname,
+                       const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
-                       const string &key_prefix, const string &key_suffix);
+                       const std::string &key_prefix,
+                       const std::string &key_suffix);
 
 // 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!
 struct FarCreateArgs {
-  const std::vector<string> &in_fnames;
-  const string &out_fname;
+  const std::vector<std::string> &in_fnames;
+  const std::string &out_fname;
   const int32 generate_keys;
   const FarType &far_type;
-  const string &key_prefix;
-  const string &key_suffix;
+  const std::string &key_prefix;
+  const std::string &key_suffix;
 
-  FarCreateArgs(const std::vector<string> &in_fnames, const string &out_fname,
-                const int32 generate_keys, const FarType &far_type,
-                const string &key_prefix, const string &key_suffix)
+  FarCreateArgs(const std::vector<std::string> &in_fnames,
+                const std::string &out_fname, const int32 generate_keys,
+                const FarType &far_type, const std::string &key_prefix,
+                const std::string &key_suffix)
       : in_fnames(in_fnames),
         out_fname(out_fname),
         generate_keys(generate_keys),
@@ -115,13 +119,14 @@ void FarCreate(FarCreateArgs *args) {
                  args->far_type, args->key_prefix, args->key_suffix);
 }
 
-void FarCreate(const std::vector<string> &in_fnames, const string &out_fname,
-               const string &arc_type, const int32 generate_keys,
-               const FarType &far_type, const string &key_prefix,
-               const string &key_suffix);
+void FarCreate(const std::vector<std::string> &in_fnames,
+               const std::string &out_fname, const std::string &arc_type,
+               const int32 generate_keys, const FarType &far_type,
+               const std::string &key_prefix, const std::string &key_suffix);
 
-using FarEqualInnerArgs = std::tuple<const string &, const string &, float,
-                                     const string &, const string &>;
+using FarEqualInnerArgs =
+    std::tuple<const std::string &, const std::string &, float,
+               const std::string &, const std::string &>;
 
 using FarEqualArgs = WithReturnValue<bool, FarEqualInnerArgs>;
 
@@ -132,14 +137,15 @@ void FarEqual(FarEqualArgs *args) {
       std::get<3>(args->args), std::get<4>(args->args));
 }
 
-bool FarEqual(const string &filename1, const string &filename2,
-              const string &arc_type, float delta = kDelta,
-              const string &begin_key = string(),
-              const string &end_key = string());
+bool FarEqual(const std::string &filename1, const std::string &filename2,
+              const std::string &arc_type, float delta = kDelta,
+              const std::string &begin_key = std::string(),
+              const std::string &end_key = std::string());
 
 using FarExtractArgs =
-    std::tuple<const std::vector<string> &, int32, const string &,
-               const string &, const string &, const string &, const string &>;
+    std::tuple<const std::vector<std::string> &, int32, const std::string &,
+               const std::string &, const std::string &, const std::string &,
+               const std::string &>;
 
 template <class Arc>
 void FarExtract(FarExtractArgs *args) {
@@ -149,13 +155,16 @@ void FarExtract(FarExtractArgs *args) {
                            std::get<6>(*args));
 }
 
-void FarExtract(const std::vector<string> &ifilenames, const string &arc_type,
-                int32 generate_filenames, const string &keys,
-                const string &key_separator, const string &range_delimiter,
-                const string &filename_prefix, const string &filename_suffix);
+void FarExtract(const std::vector<std::string> &ifilenames,
+                const std::string &arc_type, int32 generate_filenames,
+                const std::string &keys, const std::string &key_separator,
+                const std::string &range_delimiter,
+                const std::string &filename_prefix,
+                const std::string &filename_suffix);
 
-using FarInfoArgs = std::tuple<const std::vector<string> &, const string &,
-                               const string &, const bool>;
+using FarInfoArgs =
+    std::tuple<const std::vector<std::string> &, const std::string &,
+               const std::string &, const bool>;
 
 template <class Arc>
 void FarInfo(FarInfoArgs *args) {
@@ -163,12 +172,13 @@ void FarInfo(FarInfoArgs *args) {
                         std::get<2>(*args), std::get<3>(*args));
 }
 
-void FarInfo(const std::vector<string> &filenames, const string &arc_type,
-             const string &begin_key, const string &end_key,
-             const bool list_fsts);
+void FarInfo(const std::vector<std::string> &filenames,
+             const std::string &arc_type, const std::string &begin_key,
+             const std::string &end_key, const bool list_fsts);
 
-using GetFarInfoArgs = std::tuple<const std::vector<string> &, const string &,
-                                  const string &, const bool, FarInfoData *>;
+using GetFarInfoArgs =
+    std::tuple<const std::vector<std::string> &, const std::string &,
+               const std::string &, const bool, FarInfoData *>;
 
 template <class Arc>
 void GetFarInfo(GetFarInfoArgs *args) {
@@ -177,12 +187,14 @@ void GetFarInfo(GetFarInfoArgs *args) {
                            std::get<4>(*args));
 }
 
-void GetFarInfo(const std::vector<string> &filenames, const string &arc_type,
-                const string &begin_key, const string &end_key,
-                const bool list_fsts, FarInfoData *);
+void GetFarInfo(const std::vector<std::string> &filenames,
+                const std::string &arc_type, const std::string &begin_key,
+                const std::string &end_key, const bool list_fsts,
+                FarInfoData *);
 
-using FarIsomorphicInnerArgs = std::tuple<const string &, const string &, float,
-                                          const string &, const string &>;
+using FarIsomorphicInnerArgs =
+    std::tuple<const std::string &, const std::string &, float,
+               const std::string &, const std::string &>;
 
 using FarIsomorphicArgs = WithReturnValue<bool, FarIsomorphicInnerArgs>;
 
@@ -193,34 +205,32 @@ void FarIsomorphic(FarIsomorphicArgs *args) {
       std::get<3>(args->args), std::get<4>(args->args));
 }
 
-bool FarIsomorphic(const string &filename1, const string &filename2,
-                   const string &arc_type, float delta = kDelta,
-                   const string &begin_key = string(),
-                   const string &end_key = string());
+bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+                   const std::string &arc_type, float delta = kDelta,
+                   const std::string &begin_key = std::string(),
+                   const std::string &end_key = std::string());
 
 struct FarPrintStringsArgs {
-  const std::vector<string> &ifilenames;
+  const std::vector<std::string> &ifilenames;
   const FarEntryType entry_type;
   const FarTokenType token_type;
-  const string &begin_key;
-  const string &end_key;
+  const std::string &begin_key;
+  const std::string &end_key;
   const bool print_key;
   const bool print_weight;
-  const string &symbols_fname;
+  const std::string &symbols_fname;
   const bool initial_symbols;
   const int32 generate_filenames;
-  const string &filename_prefix;
-  const string &filename_suffix;
-
-  FarPrintStringsArgs(const std::vector<string> &ifilenames,
-                      const FarEntryType entry_type,
-                      const FarTokenType token_type, const string &begin_key,
-                      const string &end_key, const bool print_key,
-                      const bool print_weight, const string &symbols_fname,
-                      const bool initial_symbols,
-                      const int32 generate_filenames,
-                      const string &filename_prefix,
-                      const string &filename_suffix)
+  const std::string &filename_prefix;
+  const std::string &filename_suffix;
+
+  FarPrintStringsArgs(
+      const std::vector<std::string> &ifilenames, const FarEntryType entry_type,
+      const FarTokenType token_type, const std::string &begin_key,
+      const std::string &end_key, const bool print_key, const bool print_weight,
+      const std::string &symbols_fname, const bool initial_symbols,
+      const int32 generate_filenames, const std::string &filename_prefix,
+      const std::string &filename_suffix)
       : ifilenames(ifilenames),
         entry_type(entry_type),
         token_type(token_type),
@@ -244,14 +254,15 @@ void FarPrintStrings(FarPrintStringsArgs *args) {
       args->filename_suffix);
 }
 
-void FarPrintStrings(const std::vector<string> &ifilenames,
-                     const string &arc_type, const FarEntryType entry_type,
-                     const FarTokenType token_type, const string &begin_key,
-                     const string &end_key, const bool print_key,
-                     const bool print_weight, const string &symbols_fname,
+void FarPrintStrings(const std::vector<std::string> &ifilenames,
+                     const std::string &arc_type, const FarEntryType entry_type,
+                     const FarTokenType token_type,
+                     const std::string &begin_key, const std::string &end_key,
+                     const bool print_key, const bool print_weight,
+                     const std::string &symbols_fname,
                      const bool initial_symbols, const int32 generate_filenames,
-                     const string &filename_prefix,
-                     const string &filename_suffix);
+                     const std::string &filename_prefix,
+                     const std::string &filename_suffix);
 
 }  // namespace script
 }  // namespace fst
index 3dde419..f5dcc82 100644 (file)
 namespace fst {
 namespace script {
 
-FarType GetFarType(const string &str);
+FarType GetFarType(const std::string &str);
 
-bool GetFarEntryType(const string &str, FarEntryType *entry_type);
+bool GetFarEntryType(const std::string &str, FarEntryType *entry_type);
 
-bool GetFarTokenType(const string &str, FarTokenType *token_type);
+bool GetFarTokenType(const std::string &str, FarTokenType *token_type);
 
 void ExpandArgs(int argc, char **argv, int *argcp, char ***argvp);
 
 }  // namespace script
 
-string GetFarTypeString(FarType type);
+std::string GetFarTypeString(FarType type);
 
 }  // namespace fst
 
index 0391c1f..7100214 100644 (file)
@@ -29,8 +29,8 @@ void AccumulateStatesAndArcs(const Fst<Arc> &fst, size_t *nstate, size_t *narc,
 }
 
 struct KeyInfo {
-  string key;
-  string type;
+  std::string key;
+  std::string type;
   size_t nstate = 0;
   size_t narc = 0;
   size_t nfinal = 0;
@@ -38,19 +38,19 @@ struct KeyInfo {
 
 struct FarInfoData {
   std::vector<KeyInfo> key_infos;
-  string far_type;
-  string arc_type;
+  std::string far_type;
+  std::string arc_type;
   size_t nfst = 0;
   size_t nstate = 0;
   size_t narc = 0;
   size_t nfinal = 0;
-  std::set<string> fst_types;
+  std::set<std::string> fst_types;
 };
 
 template <class Arc>
-void GetFarInfo(const std::vector<string> &filenames, const string &begin_key,
-                const string &end_key, const bool list_fsts,
-                FarInfoData *far_info) {
+void GetFarInfo(const std::vector<std::string> &filenames,
+                const std::string &begin_key, const std::string &end_key,
+                const bool list_fsts, FarInfoData *far_info) {
   *far_info = FarInfoData();
   std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(filenames));
   if (!reader) {
@@ -84,8 +84,9 @@ void GetFarInfo(const std::vector<string> &filenames, const string &begin_key,
 }
 
 template <class Arc>
-void FarInfo(const std::vector<string> &filenames, const string &begin_key,
-             const string &end_key, const bool list_fsts) {
+void FarInfo(const std::vector<std::string> &filenames,
+             const std::string &begin_key, const std::string &end_key,
+             const bool list_fsts) {
   FarInfoData info;
   GetFarInfo<Arc>(filenames, begin_key, end_key, list_fsts, &info);
   if (!list_fsts) {
index 1e6e9cb..ede0efb 100644 (file)
 namespace fst {
 
 template <class Arc>
-bool FarIsomorphic(const string &filename1, const string &filename2,
-                   float delta = kDelta, const string &begin_key = string(),
-                   const string &end_key = string()) {
+bool FarIsomorphic(const std::string &filename1, const std::string &filename2,
+                   float delta = kDelta,
+                   const std::string &begin_key = std::string(),
+                   const std::string &end_key = std::string()) {
   std::unique_ptr<FarReader<Arc>> reader1(FarReader<Arc>::Open(filename1));
   if (!reader1) {
     LOG(ERROR) << "FarIsomorphic: Cannot open FAR file " << filename1;
index dc42840..b1e0747 100644 (file)
@@ -21,13 +21,14 @@ DECLARE_string(far_field_separator);
 namespace fst {
 
 template <class Arc>
-void FarPrintStrings(const std::vector<string> &ifilenames,
+void FarPrintStrings(const std::vector<std::string> &ifilenames,
                      FarEntryType entry_type, FarTokenType far_token_type,
-                     const string &begin_key, const string &end_key,
+                     const std::string &begin_key, const std::string &end_key,
                      bool print_key, bool print_weight,
-                     const string &symbols_fname, bool initial_symbols,
-                     int32 generate_filenames, const string &filename_prefix,
-                     const string &filename_suffix) {
+                     const std::string &symbols_fname, bool initial_symbols,
+                     int32 generate_filenames,
+                     const std::string &filename_prefix,
+                     const std::string &filename_suffix) {
   StringTokenType token_type;
   if (far_token_type == FTT_SYMBOL) {
     token_type = StringTokenType::SYMBOL;
@@ -53,7 +54,7 @@ void FarPrintStrings(const std::vector<string> &ifilenames,
   std::unique_ptr<FarReader<Arc>> far_reader(FarReader<Arc>::Open(ifilenames));
   if (!far_reader) return;
   if (!begin_key.empty()) far_reader->Find(begin_key);
-  string okey;
+  std::string okey;
   int nrep = 0;
   for (int i = 1; !far_reader->Done(); far_reader->Next(), ++i) {
     const auto &key = far_reader->GetKey();
@@ -67,7 +68,7 @@ void FarPrintStrings(const std::vector<string> &ifilenames,
     const auto *fst = far_reader->GetFst();
     if (i == 1 && initial_symbols && !syms && fst->InputSymbols())
       syms.reset(fst->InputSymbols()->Copy());
-    string str;
+    std::string str;
     VLOG(2) << "Handling key: " << key;
     StringPrinter<Arc> string_printer(token_type,
                                       syms ? syms.get() : fst->InputSymbols());
@@ -87,7 +88,7 @@ void FarPrintStrings(const std::vector<string> &ifilenames,
         sstrm << key;
         if (nrep > 0) sstrm << "." << nrep;
       }
-      string filename;
+      std::string filename;
       filename = filename_prefix + sstrm.str() + filename_suffix;
       std::ofstream ostrm(filename);
       if (!ostrm) {
index a0586cc..47c1980 100644 (file)
@@ -13,9 +13,9 @@
 namespace fst {
 namespace script {
 
-string LoadArcTypeFromFar(const string &far_fname);
+std::string LoadArcTypeFromFar(const std::string &far_fname);
 
-string LoadArcTypeFromFst(const string &fst_fname);
+std::string LoadArcTypeFromFst(const std::string &fst_fname);
 
 }  // namespace script
 }  // namespace fst
index b155e17..d5b230f 100644 (file)
@@ -35,11 +35,11 @@ static constexpr int32 kSTListFileVersion = 1;
 template <class T, class Writer>
 class STListWriter {
  public:
-  explicit STListWriter(const string &filename)
-      : stream_(filename.empty() ? &std::cout : new std::ofstream(
-                                                    filename,
-                                                    std::ios_base::out |
-                                                        std::ios_base::binary)),
+  explicit STListWriter(const std::string &filename)
+      : stream_(filename.empty() ? &std::cout
+                                 : new std::ofstream(
+                                       filename, std::ios_base::out |
+                                                     std::ios_base::binary)),
         error_(false) {
     WriteType(*stream_, kSTListMagicNumber);
     WriteType(*stream_, kSTListFileVersion);
@@ -50,12 +50,12 @@ class STListWriter {
     }
   }
 
-  static STListWriter<T, Writer> *Create(const string &filename) {
+  static STListWriter<T, Writer> *Create(const std::string &filename) {
     return new STListWriter<T, Writer>(filename);
   }
 
-  void Add(const string &key, const T &t) {
-    if (key == "") {
+  void Add(const std::string &key, const T &t) {
+    if (key.empty()) {
       FSTERROR() << "STListWriter::Add: Key empty: " << key;
       error_ = true;
     } else if (key < last_key_) {
@@ -71,14 +71,14 @@ class STListWriter {
   bool Error() const { return error_; }
 
   ~STListWriter() {
-    WriteType(*stream_, string());
+    WriteType(*stream_, std::string());
     if (stream_ != &std::cout) delete stream_;
   }
 
  private:
   Writer entry_writer_;
   std::ostream *stream_;  // Output stream.
-  string last_key_;       // Last key.
+  std::string last_key_;  // Last key.
   bool error_;
 
   STListWriter(const STListWriter &) = delete;
@@ -94,7 +94,7 @@ class STListWriter {
 template <class T, class Reader>
 class STListReader {
  public:
-  explicit STListReader(const std::vector<string> &filenames)
+  explicit STListReader(const std::vector<std::string> &filenames)
       : sources_(filenames), error_(false) {
     streams_.resize(filenames.size(), 0);
     bool has_stdin = false;
@@ -136,7 +136,7 @@ class STListReader {
         error_ = true;
         return;
       }
-      string key;
+      std::string key;
       ReadType(*streams_[i], &key);
       if (!key.empty()) heap_.push(std::make_pair(key, i));
       if (!*streams_[i]) {
@@ -161,13 +161,14 @@ class STListReader {
     }
   }
 
-  static STListReader<T, Reader> *Open(const string &filename) {
-    std::vector<string> filenames;
+  static STListReader<T, Reader> *Open(const std::string &filename) {
+    std::vector<std::string> filenames;
     filenames.push_back(filename);
     return new STListReader<T, Reader>(filenames);
   }
 
-  static STListReader<T, Reader> *Open(const std::vector<string> &filenames) {
+  static STListReader<T, Reader> *Open(
+      const std::vector<std::string> &filenames) {
     return new STListReader<T, Reader>(filenames);
   }
 
@@ -176,7 +177,7 @@ class STListReader {
     error_ = true;
   }
 
-  bool Find(const string &key) {
+  bool Find(const std::string &key) {
     FSTERROR() << "STListReader::Find: Operation not supported";
     error_ = true;
     return false;
@@ -187,7 +188,7 @@ class STListReader {
   void Next() {
     if (error_) return;
     auto current = heap_.top().second;
-    string key;
+    std::string key;
     heap_.pop();
     ReadType(*(streams_[current]), &key);
     if (!*streams_[current]) {
@@ -207,7 +208,7 @@ class STListReader {
     }
   }
 
-  const string &GetKey() const { return heap_.top().first; }
+  const std::string &GetKey() const { return heap_.top().first; }
 
   const T *GetEntry() const { return entry_.get(); }
 
@@ -216,10 +217,11 @@ class STListReader {
  private:
   Reader entry_reader_;                  // Read functor.
   std::vector<std::istream *> streams_;  // Input streams.
-  std::vector<string> sources_;          // Corresponding filenames.
-  std::priority_queue<
-      std::pair<string, size_t>, std::vector<std::pair<string, size_t>>,
-      std::greater<std::pair<string, size_t>>> heap_;  // (Key, stream id) heap
+  std::vector<std::string> sources_;     // Corresponding filenames.
+  std::priority_queue<std::pair<std::string, size_t>,
+                      std::vector<std::pair<std::string, size_t>>,
+                      std::greater<std::pair<std::string, size_t>>>
+      heap_;                          // (Key, stream id) heap
   mutable std::unique_ptr<T> entry_;  // The currently read entry.
   bool error_;
 
@@ -234,7 +236,7 @@ class STListReader {
 //    void Read(std::istream &strm, const string &filename);
 //  };
 template <class Header>
-bool ReadSTListHeader(const string &filename, Header *header) {
+bool ReadSTListHeader(const std::string &filename, Header *header) {
   if (filename.empty()) {
     LOG(ERROR) << "ReadSTListHeader: Can't read header from standard input";
     return false;
@@ -256,7 +258,7 @@ bool ReadSTListHeader(const string &filename, Header *header) {
     LOG(ERROR) << "ReadSTListHeader: Wrong file version: " << filename;
     return false;
   }
-  string key;
+  std::string key;
   ReadType(strm, &key);
   header->Read(strm, filename + ":" + key);
   if (!strm) {
@@ -266,7 +268,7 @@ bool ReadSTListHeader(const string &filename, Header *header) {
   return true;
 }
 
-bool IsSTList(const string &filename);
+bool IsSTList(const std::string &filename);
 
 }  // namespace fst
 
index 2a01bb1..377c495 100644 (file)
@@ -31,7 +31,7 @@ static constexpr int32 kSTTableFileVersion = 1;
 template <class T, class Writer>
 class STTableWriter {
  public:
-  explicit STTableWriter(const string &filename)
+  explicit STTableWriter(const std::string &filename)
       : stream_(filename, std::ios_base::out | std::ios_base::binary),
         error_(false) {
     WriteType(stream_, kSTTableMagicNumber);
@@ -43,7 +43,7 @@ class STTableWriter {
     }
   }
 
-  static STTableWriter<T, Writer> *Create(const string &filename) {
+  static STTableWriter<T, Writer> *Create(const std::string &filename) {
     if (filename.empty()) {
       LOG(ERROR) << "STTableWriter: Writing to standard out unsupported.";
       return nullptr;
@@ -51,8 +51,8 @@ class STTableWriter {
     return new STTableWriter<T, Writer>(filename);
   }
 
-  void Add(const string &key, const T &t) {
-    if (key == "") {
+  void Add(const std::string &key, const T &t) {
+    if (key.empty()) {
       FSTERROR() << "STTableWriter::Add: Key empty: " << key;
       error_ = true;
     } else if (key < last_key_) {
@@ -77,7 +77,7 @@ class STTableWriter {
   Writer entry_writer_;
   std::ofstream stream_;
   std::vector<int64> positions_;  // Position in file of each key-entry pair.
-  string last_key_;               // Last key.
+  std::string last_key_;          // Last key.
   bool error_;
 
   STTableWriter(const STTableWriter &) = delete;
@@ -94,7 +94,7 @@ class STTableWriter {
 template <class T, class Reader>
 class STTableReader {
  public:
-  explicit STTableReader(const std::vector<string> &filenames)
+  explicit STTableReader(const std::vector<std::string> &filenames)
       : sources_(filenames), error_(false) {
     compare_.reset(new Compare(&keys_));
     keys_.resize(filenames.size());
@@ -151,17 +151,18 @@ class STTableReader {
     for (auto &stream : streams_) delete stream;
   }
 
-  static STTableReader<T, Reader> *Open(const string &filename) {
+  static STTableReader<T, Reader> *Open(const std::string &filename) {
     if (filename.empty()) {
       LOG(ERROR) << "STTableReader: Operation not supported on standard input";
       return nullptr;
     }
-    std::vector<string> filenames;
+    std::vector<std::string> filenames;
     filenames.push_back(filename);
     return new STTableReader<T, Reader>(filenames);
   }
 
-  static STTableReader<T, Reader> *Open(const std::vector<string> &filenames) {
+  static STTableReader<T, Reader> *Open(
+      const std::vector<std::string> &filenames) {
     return new STTableReader<T, Reader>(filenames);
   }
 
@@ -172,7 +173,7 @@ class STTableReader {
     MakeHeap();
   }
 
-  bool Find(const string &key) {
+  bool Find(const std::string &key) {
     if (error_) return false;
     for (size_t i = 0; i < streams_.size(); ++i) LowerBound(i, key);
     MakeHeap();
@@ -199,7 +200,7 @@ class STTableReader {
     if (!heap_.empty()) PopHeap();
   }
 
-  const string &GetKey() const { return keys_[current_]; }
+  const std::string &GetKey() const { return keys_[current_]; }
 
   const T *GetEntry() const { return entry_.get(); }
 
@@ -208,19 +209,19 @@ class STTableReader {
  private:
   // Comparison functor used to compare stream IDs in the heap.
   struct Compare {
-    explicit Compare(const std::vector<string> *keys) : keys(keys) {}
+    explicit Compare(const std::vector<std::string> *keys) : keys(keys) {}
 
     bool operator()(size_t i, size_t j) const {
       return (*keys)[i] > (*keys)[j];
     };
 
    private:
-    const std::vector<string> *keys;
+    const std::vector<std::string> *keys;
   };
 
   // Positions the stream at the position corresponding to the lower bound for
   // the specified key.
-  void LowerBound(size_t id, const string &find_key) {
+  void LowerBound(size_t id, const std::string &find_key) {
     auto *strm = streams_[id];
     const auto &positions = positions_[id];
     if (positions.empty()) return;
@@ -229,7 +230,7 @@ class STTableReader {
     while (low < high) {
       size_t mid = (low + high) / 2;
       strm->seekg(positions[mid]);
-      string key;
+      std::string key;
       ReadType(*strm, &key);
       if (key > find_key) {
         high = mid;
@@ -286,9 +287,9 @@ class STTableReader {
 
   Reader entry_reader_;
   std::vector<std::istream *> streams_;        // Input streams.
-  std::vector<string> sources_;                // Corresponding file names.
+  std::vector<std::string> sources_;           // Corresponding file names.
   std::vector<std::vector<int64>> positions_;  // Index of positions.
-  std::vector<string> keys_;  // Lowest unread key for each stream.
+  std::vector<std::string> keys_;  // Lowest unread key for each stream.
   std::vector<int64> heap_;   // Heap containing ID of streams with unread keys.
   int64 current_;             // ID of current stream to be read.
   std::unique_ptr<Compare> compare_;  // Functor comparing stream IDs.
@@ -303,7 +304,7 @@ class STTableReader {
 //     void Read(std::istream &istrm, const string &filename);
 //   };
 template <class Header>
-bool ReadSTTableHeader(const string &filename, Header *header) {
+bool ReadSTTableHeader(const std::string &filename, Header *header) {
   if (filename.empty()) {
     LOG(ERROR) << "ReadSTTable: Can't read header from standard input";
     return false;
@@ -336,7 +337,7 @@ bool ReadSTTableHeader(const string &filename, Header *header) {
   strm.seekg(-2 * static_cast<int>(sizeof(int64)), std::ios_base::end);
   ReadType(strm, &i);  // Reads position for last entry in file.
   strm.seekg(i);
-  string key;
+  std::string key;
   ReadType(strm, &key);
   header->Read(strm, filename + ":" + key);
   if (strm.fail()) {
@@ -346,7 +347,7 @@ bool ReadSTTableHeader(const string &filename, Header *header) {
   return true;
 }
 
-bool IsSTTable(const string &filename);
+bool IsSTTable(const std::string &filename);
 
 }  // namespace fst
 
index a6ac727..18d2097 100644 (file)
@@ -27,11 +27,12 @@ template <class A>
 class FeatureGroupBuilder;
 
 // For logging purposes
-inline string TranslateLabel(int64 label, const SymbolTable *syms);
+inline std::string TranslateLabel(int64 label, const SymbolTable *syms);
 template <class Iterator>
-string JoinLabels(Iterator begin, Iterator end, const SymbolTable *syms);
+std::string JoinLabels(Iterator begin, Iterator end, const SymbolTable *syms);
 template <class Label>
-string JoinLabels(const std::vector<Label> &labels, const SymbolTable *syms);
+std::string JoinLabels(const std::vector<Label> &labels,
+                       const SymbolTable *syms);
 
 // Guesses the appropriate boundary label (start- or end-of-sentence)
 // for all labels equal to `boundary` and modifies the `sequence`
@@ -312,7 +313,7 @@ class FeatureGroupBuilder {
   // Reconstruct the path from trie root to given node for logging.
   bool TrieDfs(const Topology &topology, int cur, int target,
                std::vector<InputOutputLabel> *path) const;
-  string TriePath(int node, const Topology &topology) const;
+  std::string TriePath(int node, const Topology &topology) const;
 
   bool error_;
   size_t future_size_;
@@ -980,8 +981,8 @@ bool FeatureGroupBuilder<A>::TrieDfs(
 }
 
 template <class A>
-string FeatureGroupBuilder<A>::TriePath(int node,
-                                        const Topology &topology) const {
+std::string FeatureGroupBuilder<A>::TriePath(int node,
+                                             const Topology &topology) const {
   std::vector<InputOutputLabel> labels;
   TrieDfs(topology, topology.Root(), node, &labels);
   bool first = true;
@@ -1000,8 +1001,8 @@ string FeatureGroupBuilder<A>::TriePath(int node,
   return strm.str();
 }
 
-inline string TranslateLabel(int64 label, const SymbolTable *syms) {
-  string ret;
+inline std::string TranslateLabel(int64 label, const SymbolTable *syms) {
+  std::string ret;
   if (syms != nullptr) ret += syms->Find(label);
   if (ret.empty()) {
     std::ostringstream strm;
@@ -1012,7 +1013,7 @@ inline string TranslateLabel(int64 label, const SymbolTable *syms) {
 }
 
 template <class Iterator>
-string JoinLabels(Iterator begin, Iterator end, const SymbolTable *syms) {
+std::string JoinLabels(Iterator begin, Iterator end, const SymbolTable *syms) {
   if (begin == end) return "<empty>";
   std::ostringstream strm;
   bool first = true;
@@ -1027,7 +1028,8 @@ string JoinLabels(Iterator begin, Iterator end, const SymbolTable *syms) {
 }
 
 template <class Label>
-string JoinLabels(const std::vector<Label> &labels, const SymbolTable *syms) {
+std::string JoinLabels(const std::vector<Label> &labels,
+                       const SymbolTable *syms) {
   return JoinLabels(labels.begin(), labels.end(), syms);
 }
 
index 3b39c29..ae348eb 100644 (file)
@@ -329,7 +329,7 @@ class FeatureGroup {
 
   size_t Delay() const { return delay_; }
 
-  string Stats() const;
+  std::string Stats() const;
 
  private:
   // Label along the arcs on the trie. `kNoLabel` means anything
@@ -463,7 +463,7 @@ inline int FeatureGroup<A>::FindFirstMatch(InputOutputLabel label,
 }
 
 template <class A>
-inline string FeatureGroup<A>::Stats() const {
+inline std::string FeatureGroup<A>::Stats() const {
   std::ostringstream strm;
   int num_states = 2;
   for (int i = 2; i < next_state_.size(); ++i)
index e4239a8..00f8329 100644 (file)
@@ -270,13 +270,13 @@ class LinearTaggerFstImpl : public CacheImpl<A> {
 
   std::shared_ptr<const LinearFstData<A>> data_;
   size_t delay_;
-  // Mapping from internal state tuple to *non-consecutive* ids
+  // Mapping from internal state tuple to *non-consecutive* IDs.
   Collection<StateId, Label> ngrams_;
-  // Mapping from non-consecutive id to actual state id
+  // Mapping from non-consecutive id to actual state ID.
   CompactHashBiTable<StateId, StateId, std::hash<StateId>> condensed_;
-  // Two frequently used vectors, reuse to avoid repeated heap
-  // allocation
-  std::vector<Label> state_stub_, next_stub_;
+  // Two frequently used vectors, reuse to avoid repeated heap allocation.
+  std::vector<Label> state_stub_;
+  std::vector<Label> next_stub_;
 
   LinearTaggerFstImpl &operator=(const LinearTaggerFstImpl &) = delete;
 };
@@ -493,7 +493,7 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
     return new LinearFstMatcherTpl<LinearTaggerFst<A>>(this, match_type);
   }
 
-  static LinearTaggerFst<A> *Read(const string &filename) {
+  static LinearTaggerFst<A> *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -513,7 +513,7 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
     return impl ? new LinearTaggerFst<A>(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     if (!filename.empty()) {
       std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
@@ -778,22 +778,22 @@ class LinearClassifierFstImpl : public CacheImpl<A> {
   void FillState(StateId s, std::vector<Label> *output) {
     s = condensed_.FindEntry(s);
     for (NGramIterator it = ngrams_.FindSet(s); !it.Done(); it.Next()) {
-      Label label = it.Element();
-      output->push_back(label);
+      output->emplace_back(it.Element());
     }
   }
 
   std::shared_ptr<const LinearFstData<A>> data_;
   // Division of groups in `data_`; num_classes_ * num_groups_ ==
   // data_->NumGroups().
-  size_t num_classes_, num_groups_;
-  // Mapping from internal state tuple to *non-consecutive* ids
+  size_t num_classes_;
+  size_t num_groups_;
+  // Mapping from internal state tuple to *non-consecutive* IDs.
   Collection<StateId, Label> ngrams_;
-  // Mapping from non-consecutive id to actual state id
+  // Mapping from non-consecutive id to actual state ID.
   CompactHashBiTable<StateId, StateId, std::hash<StateId>> condensed_;
-  // Two frequently used vectors, reuse to avoid repeated heap
-  // allocation
-  std::vector<Label> state_stub_, next_stub_;
+  // Two frequently used vectors, reuse to avoid repeated heap allocation.
+  std::vector<Label> state_stub_;
+  std::vector<Label> next_stub_;
 
   void operator=(const LinearClassifierFstImpl<A> &) = delete;
 };
@@ -950,7 +950,7 @@ class LinearClassifierFst
     return new LinearFstMatcherTpl<LinearClassifierFst<A>>(this, match_type);
   }
 
-  static LinearClassifierFst<A> *Read(const string &filename) {
+  static LinearClassifierFst<A> *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -972,7 +972,7 @@ class LinearClassifierFst
                 : nullptr;
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     if (!filename.empty()) {
       std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
index 54106d2..0b306c1 100644 (file)
@@ -25,9 +25,10 @@ DECLARE_bool(classifier);
 
 namespace fst {
 namespace script {
-typedef std::tuple<const string &, const string &, const string &, char **, int,
-                   const string &, const string &, const string &,
-                   const string &>
+typedef std::tuple<const std::string &, const std::string &,
+                   const std::string &, char **, int, const std::string &,
+                   const std::string &, const std::string &,
+                   const std::string &>
     LinearCompileArgs;
 
 bool ValidateDelimiter();
@@ -40,7 +41,7 @@ bool ValidateEmptySymbol();
 // either returns `kNoLabel` for later processing or decides the label
 // right away.
 template <class Arc>
-inline typename Arc::Label LookUp(const string &str, SymbolTable *syms) {
+inline typename Arc::Label LookUp(const std::string &str, SymbolTable *syms) {
   if (str == FLAGS_start_symbol)
     return str == FLAGS_end_symbol ? kNoLabel
                                    : LinearFstData<Arc>::kStartOfSentence;
@@ -53,11 +54,11 @@ inline typename Arc::Label LookUp(const string &str, SymbolTable *syms) {
 // Splits `str` with `delim` as the delimiter and stores the labels in
 // `output`.
 template <class Arc>
-void SplitAndPush(const string &str, const char delim, SymbolTable *syms,
+void SplitAndPush(const std::string &str, const char delim, SymbolTable *syms,
                   std::vector<typename Arc::Label> *output) {
   if (str == FLAGS_empty_symbol) return;
   std::istringstream strm(str);
-  string buf;
+  std::string buf;
   while (std::getline(strm, buf, delim))
     output->push_back(LookUp<Arc>(buf, syms));
 }
@@ -82,7 +83,7 @@ size_t ReplaceCopy(InputIterator first, InputIterator last,
 }
 
 template <class Arc>
-bool GetVocabRecord(const string &vocab, std::istream &strm,  // NOLINT
+bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
                     SymbolTable *isyms, SymbolTable *fsyms, SymbolTable *osyms,
                     typename Arc::Label *word,
                     std::vector<typename Arc::Label> *feature_labels,
@@ -90,7 +91,7 @@ bool GetVocabRecord(const string &vocab, std::istream &strm,  // NOLINT
                     size_t *num_line);
 
 template <class Arc>
-bool GetModelRecord(const string &model, std::istream &strm,  // NOLINT
+bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
                     SymbolTable *fsyms, SymbolTable *osyms,
                     std::vector<typename Arc::Label> *input_labels,
                     std::vector<typename Arc::Label> *output_labels,
@@ -103,12 +104,12 @@ bool GetModelRecord(const string &model, std::istream &strm,  // NOLINT
 // where features and possible output are `FLAGS_delimiter`-delimited lists of
 // tokens
 template <class Arc>
-void AddVocab(const string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
+void AddVocab(const std::string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
               SymbolTable *osyms, LinearFstDataBuilder<Arc> *builder) {
   std::ifstream in(vocab);
   if (!in) LOG(FATAL) << "Can't open file: " << vocab;
   size_t num_line = 0, num_added = 0;
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   std::vector<typename Arc::Label> feature_labels, possible_labels;
   typename Arc::Label word;
   while (GetVocabRecord<Arc>(vocab, in, isyms, fsyms, osyms, &word,
@@ -127,13 +128,13 @@ void AddVocab(const string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
 }
 
 template <class Arc>
-void AddVocab(const string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
+void AddVocab(const std::string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
               SymbolTable *osyms,
               LinearClassifierFstDataBuilder<Arc> *builder) {
   std::ifstream in(vocab);
   if (!in) LOG(FATAL) << "Can't open file: " << vocab;
   size_t num_line = 0, num_added = 0;
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   std::vector<typename Arc::Label> feature_labels, possible_labels;
   typename Arc::Label word;
   while (GetVocabRecord<Arc>(vocab, in, isyms, fsyms, osyms, &word,
@@ -163,11 +164,11 @@ void AddVocab(const string &vocab, SymbolTable *isyms, SymbolTable *fsyms,
 // last label is the output of the feature position before the history
 // boundary.
 template <class Arc>
-void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
+void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
               LinearFstDataBuilder<Arc> *builder) {
   std::ifstream in(model);
   if (!in) LOG(FATAL) << "Can't open file: " << model;
-  string line;
+  std::string line;
   std::getline(in, line);
   if (!in) LOG(FATAL) << "Empty file: " << model;
   size_t future_size;
@@ -181,7 +182,7 @@ void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
   VLOG(1) << "Group " << group << ": from " << model << "; future size is "
           << future_size << ".";
   // Add the rest of lines as a single feature group
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   std::vector<typename Arc::Label> input_labels, output_labels;
   typename Arc::Weight weight;
   while (GetModelRecord<Arc>(model, in, fsyms, osyms, &input_labels,
@@ -215,11 +216,11 @@ void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
 }
 
 template <class Arc>
-void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
+void AddModel(const std::string &model, SymbolTable *fsyms, SymbolTable *osyms,
               LinearClassifierFstDataBuilder<Arc> *builder) {
   std::ifstream in(model);
   if (!in) LOG(FATAL) << "Can't open file: " << model;
-  string line;
+  std::string line;
   std::getline(in, line);
   if (!in) LOG(FATAL) << "Empty file: " << model;
   size_t future_size;
@@ -236,7 +237,7 @@ void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
   VLOG(1) << "Group " << group << ": from " << model << "; future size is "
           << future_size << ".";
   // Add the rest of lines as a single feature group
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   std::vector<typename Arc::Label> input_labels, output_labels;
   typename Arc::Weight weight;
   while (GetModelRecord<Arc>(model, in, fsyms, osyms, &input_labels,
@@ -263,20 +264,20 @@ void AddModel(const string &model, SymbolTable *fsyms, SymbolTable *osyms,
           << num_line << " lines.";
 }
 
-void SplitByWhitespace(const string &str, std::vector<string> *out);
+void SplitByWhitespace(const std::string &str, std::vector<std::string> *out);
 int ScanNumClasses(char **models, int models_length);
 
 template <class Arc>
 void LinearCompileTpl(LinearCompileArgs *args) {
-  const string &epsilon_symbol = std::get<0>(*args);
-  const string &unknown_symbol = std::get<1>(*args);
-  const string &vocab = std::get<2>(*args);
+  const std::string &epsilon_symbol = std::get<0>(*args);
+  const std::string &unknown_symbol = std::get<1>(*args);
+  const std::string &vocab = std::get<2>(*args);
   char **models = std::get<3>(*args);
   const int models_length = std::get<4>(*args);
-  const string &out = std::get<5>(*args);
-  const string &save_isymbols = std::get<6>(*args);
-  const string &save_fsymbols = std::get<7>(*args);
-  const string &save_osymbols = std::get<8>(*args);
+  const std::string &out = std::get<5>(*args);
+  const std::string &save_isymbols = std::get<6>(*args);
+  const std::string &save_fsymbols = std::get<7>(*args);
+  const std::string &save_osymbols = std::get<8>(*args);
 
   SymbolTable isyms,  // input (e.g. word tokens)
       osyms,          // output (e.g. tags)
@@ -317,24 +318,26 @@ void LinearCompileTpl(LinearCompileArgs *args) {
   if (!save_osymbols.empty()) osyms.WriteText(save_osymbols);
 }
 
-void LinearCompile(const string &arc_type, const string &epsilon_symbol,
-                   const string &unknown_symbol, const string &vocab,
-                   char **models, int models_len, const string &out,
-                   const string &save_isymbols, const string &save_fsymbols,
-                   const string &save_osymbols);
+void LinearCompile(const std::string &arc_type,
+                   const std::string &epsilon_symbol,
+                   const std::string &unknown_symbol, const std::string &vocab,
+                   char **models, int models_len, const std::string &out,
+                   const std::string &save_isymbols,
+                   const std::string &save_fsymbols,
+                   const std::string &save_osymbols);
 
 template <class Arc>
-bool GetVocabRecord(const string &vocab, std::istream &strm,  // NOLINT
+bool GetVocabRecord(const std::string &vocab, std::istream &strm,  // NOLINT
                     SymbolTable *isyms, SymbolTable *fsyms, SymbolTable *osyms,
                     typename Arc::Label *word,
                     std::vector<typename Arc::Label> *feature_labels,
                     std::vector<typename Arc::Label> *possible_labels,
                     size_t *num_line) {
-  string line;
+  std::string line;
   if (!std::getline(strm, line)) return false;
   ++(*num_line);
 
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   SplitByWhitespace(line, &fields);
   if (fields.size() != 3)
     LOG(FATAL) << "Wrong number of fields in source " << vocab << ", line "
@@ -353,16 +356,16 @@ bool GetVocabRecord(const string &vocab, std::istream &strm,  // NOLINT
 }
 
 template <class Arc>
-bool GetModelRecord(const string &model, std::istream &strm,  // NOLINT
+bool GetModelRecord(const std::string &model, std::istream &strm,  // NOLINT
                     SymbolTable *fsyms, SymbolTable *osyms,
                     std::vector<typename Arc::Label> *input_labels,
                     std::vector<typename Arc::Label> *output_labels,
                     typename Arc::Weight *weight, size_t *num_line) {
-  string line;
+  std::string line;
   if (!std::getline(strm, line)) return false;
   ++(*num_line);
 
-  std::vector<string> fields;
+  std::vector<std::string> fields;
   SplitByWhitespace(line, &fields);
   if (fields.size() != 3)
     LOG(FATAL) << "Wrong number of fields in source " << model << ", line "
index 512fcfa..ac45ab6 100644 (file)
@@ -26,9 +26,9 @@ class MPdtInfo {
            const std::vector<std::pair<Label, Label>> &parens,
            const std::vector<Label> &assignments);
 
-  const string &FstType() const { return fst_type_; }
+  const std::string &FstType() const { return fst_type_; }
 
-  const string &ArcType() const { return Arc::Type(); }
+  const std::string &ArcType() const { return Arc::Type(); }
 
   int64 NumStates() const { return nstates_; }
 
@@ -58,7 +58,7 @@ class MPdtInfo {
   void Print();
 
  private:
-  string fst_type_;
+  std::string fst_type_;
   int64 nstates_;
   int64 narcs_;
   int64 nopen_parens_[nlevels];
index 77ff757..76b6575 100644 (file)
@@ -145,12 +145,12 @@ class MPdtStack {
   }
 
   // TODO(rws): For debugging purposes only: remove later.
-  string PrintConfig(const Config &config) const {
-    string result = "[";
+  std::string PrintConfig(const Config &config) const {
+    std::string result = "[";
     for (Level i = 0; i < nlevels; ++i) {
       char s[128];
       snprintf(s, sizeof(s), "%d", config[i]);
-      result += string(s);
+      result += std::string(s);
       if (i < nlevels - 1) result += ", ";
     }
     result += "]";
index 38f9f96..d7b98ac 100644 (file)
@@ -18,7 +18,7 @@ namespace fst {
 
 // Returns true on success.
 template <typename Label>
-bool ReadLabelTriples(const string &filename,
+bool ReadLabelTriples(const std::string &filename,
                       std::vector<std::pair<Label, Label>> *pairs,
                       std::vector<Label> *assignments,
                       bool allow_negative = false) {
@@ -58,7 +58,7 @@ bool ReadLabelTriples(const string &filename,
 
 // Returns true on success.
 template <typename Label>
-bool WriteLabelTriples(const string &filename,
+bool WriteLabelTriples(const std::string &filename,
                        const std::vector<std::pair<Label, Label>> &pairs,
                        const std::vector<Label> &assignments) {
   if (pairs.size() != assignments.size()) {
index 8183a8c..2c2fa76 100644 (file)
@@ -8,9 +8,9 @@
 #ifndef FST_EXTENSIONS_NGRAM_NGRAM_FST_H_
 #define FST_EXTENSIONS_NGRAM_NGRAM_FST_H_
 
-#include <stddef.h>
-#include <string.h>
 #include <algorithm>
+#include <cstddef>
+#include <cstring>
 #include <iostream>
 #include <string>
 #include <utility>
 
 #include <fst/compat.h>
 #include <fst/log.h>
-#include <fstream>
 #include <fst/extensions/ngram/bitmap-index.h>
+#include <fstream>
 #include <fst/fstlib.h>
 #include <fst/mapped-file.h>
 
 namespace fst {
 template <class A>
 class NGramFst;
+
 template <class A>
 class NGramFstMatcher;
 
@@ -96,7 +97,7 @@ class NGramFstImpl : public FstImpl<A> {
 
   static NGramFstImpl<A> *Read(std::istream &strm,  // NOLINT
                                const FstReadOptions &opts) {
-    NGramFstImpl<A> *impl = new NGramFstImpl();
+    auto impl = std::make_unique<NGramFstImpl<A>>();
     FstHeader hdr;
     if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) return 0;
     uint64 num_states, num_futures, num_final;
@@ -116,12 +117,9 @@ class NGramFstImpl : public FstImpl<A> {
     memcpy(data + sizeof(num_states) + sizeof(num_futures),
            reinterpret_cast<char *>(&num_final), sizeof(num_final));
     strm.read(data + offset, size - offset);
-    if (strm.fail()) {
-      delete impl;
-      return nullptr;
-    }
+    if (strm.fail()) return nullptr;
     impl->Init(data, false, data_region);
-    return impl;
+    return impl.release();
   }
 
   bool Write(std::ostream &strm,  // NOLINT
@@ -382,7 +380,7 @@ class NGramFst : public ImplToExpandedFst<internal::NGramFstImpl<A>> {
     return impl ? new NGramFst<A>(std::shared_ptr<Impl>(impl)) : nullptr;
   }
 
-  static NGramFst<A> *Read(const string &filename) {
+  static NGramFst<A> *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -400,7 +398,7 @@ class NGramFst : public ImplToExpandedFst<internal::NGramFstImpl<A>> {
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<A>::WriteFile(filename);
   }
 
index e7276db..c6e6e48 100644 (file)
@@ -6,9 +6,17 @@
 
 #include <fst/types.h>
 
-#ifdef __BMI2__
+#if defined( __arm__)  // 32-bit ARM
+
+// Returns the position (0-63) of the r-th 1 bit in v.
+// 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
+uint32 nth_bit(uint64 v, uint32 r);
+
+#elif defined(__BMI2__)  // Intel Bit Manipulation Instruction Set 2
 // PDEP requires BMI2.
 
+#include <immintrin.h>
+
 // Returns the position (0-63) of the r-th 1 bit in v.
 // 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
 inline uint32 nth_bit(uint64 v, uint32 r) {
@@ -16,7 +24,7 @@ inline uint32 nth_bit(uint64 v, uint32 r) {
   return __builtin_ctzll(_pdep_u64(uint64{1} << (r - 1), v));
 }
 
-#else  // !defined(__BMI2__)
+#else  // !defined(__BMI2__) && !defined(__arm__)
 
 extern const uint32 nth_bit_bit_offset[];
 
index eeee781..abb55fb 100644 (file)
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include <fst/log.h>
-
 #include <fst/extensions/pdt/paren.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/extensions/pdt/reverse.h>
index 69dd150..30bb95b 100644 (file)
@@ -12,9 +12,9 @@
 namespace fst {
 namespace script {
 
-bool GetPdtComposeFilter(const string &str, PdtComposeFilter *cf);
+bool GetPdtComposeFilter(const std::string &str, PdtComposeFilter *cf);
 
-bool GetPdtParserType(const string &str, PdtParserType *pt);
+bool GetPdtParserType(const std::string &str, PdtParserType *pt);
 
 }  // namespace script
 }  // namespace fst
index 3de5477..dee6e6f 100644 (file)
@@ -26,9 +26,9 @@ class PdtInfo {
   PdtInfo(const Fst<Arc> &fst,
           const std::vector<std::pair<Label, Label>> &parents);
 
-  const string &FstType() const { return fst_type_; }
+  const std::string &FstType() const { return fst_type_; }
 
-  const string &ArcType() const { return Arc::Type(); }
+  const std::string &ArcType() const { return Arc::Type(); }
 
   int64 NumStates() const { return nstates_; }
 
@@ -47,7 +47,7 @@ class PdtInfo {
   int64 NumCloseParenStates() const { return nclose_paren_states_; }
 
  private:
-  string fst_type_;
+  std::string fst_type_;
   int64 nstates_;
   int64 narcs_;
   int64 nopen_parens_;
index bdf5b4e..a578a37 100644 (file)
 #include <vector>
 
 #include <fst/log.h>
-#include <fst/compose.h>  // for ComposeOptions
-#include <fst/util.h>
-
-#include <fst/script/arg-packs.h>
-#include <fst/script/fstscript.h>
-#include <fst/script/shortest-path.h>
-
 #include <fst/extensions/pdt/compose.h>
 #include <fst/extensions/pdt/expand.h>
 #include <fst/extensions/pdt/info.h>
 #include <fst/extensions/pdt/replace.h>
 #include <fst/extensions/pdt/reverse.h>
 #include <fst/extensions/pdt/shortest-path.h>
+#include <fst/compose.h>  // for ComposeOptions
+#include <fst/util.h>
+#include <fst/script/arg-packs.h>
+#include <fst/script/fstscript.h>
+#include <fst/script/shortest-path.h>
 
 namespace fst {
 namespace script {
@@ -99,7 +97,7 @@ void PdtExpand(const FstClass &ifst, const std::vector<LabelPair> &parens,
 using PdtReplaceArgs =
     std::tuple<const std::vector<LabelFstClassPair> &, MutableFstClass *,
                std::vector<LabelPair> *, int64, PdtParserType, int64,
-               const string &, const string &>;
+               const std::string &, const std::string &>;
 
 template <class Arc>
 void PdtReplace(PdtReplaceArgs *args) {
@@ -127,8 +125,8 @@ void PdtReplace(const std::vector<LabelFstClassPair> &pairs,
                 MutableFstClass *ofst, std::vector<LabelPair> *parens,
                 int64 root, PdtParserType parser_type = PDT_LEFT_PARSER,
                 int64 start_paren_labels = kNoLabel,
-                const string &left_paren_prefix = "(_",
-                const string &right_paren_prefix = "_)");
+                const std::string &left_paren_prefix = "(_",
+                const std::string &right_paren_prefix = "_)");
 
 using PdtReverseArgs =
     std::tuple<const FstClass &, const std::vector<LabelPair> &,
index 76341e8..fd75e30 100644 (file)
@@ -13,8 +13,8 @@
 #include <utility>
 #include <vector>
 
-#include <fst/replace.h>
 #include <fst/replace-util.h>
+#include <fst/replace.h>
 #include <fst/symbol-table-ops.h>
 
 namespace fst {
@@ -65,20 +65,21 @@ 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 = PDT_LEFT_PARSER,
                              Label start_paren_labels = kNoLabel,
-                             string left_paren_prefix = "(_",
-                             string right_paren_prefix = ")_") :
-      root(root), type(type), start_paren_labels(start_paren_labels),
-      left_paren_prefix(std::move(left_paren_prefix)),
-      right_paren_prefix(std::move(right_paren_prefix)) {}
+                             std::string left_paren_prefix = "(_",
+                             std::string right_paren_prefix = ")_")
+      : root(root),
+        type(type),
+        start_paren_labels(start_paren_labels),
+        left_paren_prefix(std::move(left_paren_prefix)),
+        right_paren_prefix(std::move(right_paren_prefix)) {}
 
   Label root;
   PdtParserType type;
   Label start_paren_labels;
-  const string left_paren_prefix;
-  const string right_paren_prefix;
+  const std::string left_paren_prefix;
+  const std::string right_paren_prefix;
 };
 
 // PdtParser: Base PDT parser class common to specific parsers.
@@ -214,8 +215,8 @@ class PdtParser {
   Label root_;
   // Index to use for the first parenthesis.
   Label start_paren_labels_;
-  const string left_paren_prefix_;
-  const string right_paren_prefix_;
+  const std::string left_paren_prefix_;
+  const std::string right_paren_prefix_;
   // Maps from non-terminal label to FST ID.
   std::unordered_map<Label, StateId> label2id_;
   // Given an output state, specifies the input FST (label, state) pair.
index 591c1ea..2483c23 100644 (file)
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include <fst/log.h>
-
 #include <fst/extensions/pdt/paren.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/shortest-path.h>
index db40d61..acc51c9 100644 (file)
@@ -59,7 +59,7 @@ class PhiFstMatcherData {
   MatcherRewriteMode RewriteMode() const { return rewrite_mode_; }
 
  private:
-  static MatcherRewriteMode RewriteMode(const string &mode) {
+  static MatcherRewriteMode RewriteMode(const std::string &mode) {
     if (mode == "auto") return MATCHER_REWRITE_AUTO;
     if (mode == "always") return MATCHER_REWRITE_ALWAYS;
     if (mode == "never") return MATCHER_REWRITE_NEVER;
index ababecc..f51677d 100644 (file)
@@ -49,7 +49,7 @@ class RhoFstMatcherData {
   MatcherRewriteMode RewriteMode() const { return rewrite_mode_; }
 
  private:
-  static MatcherRewriteMode RewriteMode(const string &mode) {
+  static MatcherRewriteMode RewriteMode(const std::string &mode) {
     if (mode == "auto") return MATCHER_REWRITE_AUTO;
     if (mode == "always") return MATCHER_REWRITE_ALWAYS;
     if (mode == "never") return MATCHER_REWRITE_NEVER;
index 0d6cfd0..9e870ef 100644 (file)
@@ -49,7 +49,7 @@ class SigmaFstMatcherData {
   MatcherRewriteMode RewriteMode() const { return rewrite_mode_; }
 
  private:
-  static MatcherRewriteMode RewriteMode(const string &mode) {
+  static MatcherRewriteMode RewriteMode(const std::string &mode) {
     if (mode == "auto") return MATCHER_REWRITE_AUTO;
     if (mode == "always") return MATCHER_REWRITE_ALWAYS;
     if (mode == "never") return MATCHER_REWRITE_NEVER;
index 30e0232..0a854d3 100644 (file)
@@ -95,6 +95,27 @@ class IdentityFactor {
   void Reset() {}
 };
 
+// Factor the Fst to unfold it as needed so that every two paths leading to the
+// same state have the same weight. Requires applying only to arc weights
+// (FactorWeightOptions::mode == kFactorArcWeights).
+template <class W>
+class OneFactor {
+ public:
+  explicit OneFactor(const W &w) : weight_(w), done_(w == W::One()) {}
+
+  bool Done() const { return done_; }
+
+  void Next() { done_ = true; }
+
+  std::pair<W, W> Value() const { return std::make_pair(W::One(), weight_); }
+
+  void Reset() { done_ = weight_ == W::One(); }
+
+ private:
+  W weight_;
+  bool done_;
+};
+
 // Factors a StringWeight w as 'ab' where 'a' is a label.
 template <typename Label, StringType S = STRING_LEFT>
 class StringFactor {
@@ -260,11 +281,10 @@ class FactorWeightFstImpl : public CacheImpl<Arc> {
   Weight Final(StateId s) {
     if (!HasFinal(s)) {
       const auto &element = elements_[s];
-      // TODO(sorenj): fix so cast is unnecessary
       const auto weight =
           element.state == kNoStateId
               ? element.weight
-              : (Weight)Times(element.weight, fst_->Final(element.state));
+              : Times(element.weight, fst_->Final(element.state));
       FactorIterator siter(weight);
       if (!(mode_ & kFactorFinalWeights) || siter.Done()) {
         SetFinal(s, weight);
@@ -319,7 +339,7 @@ class FactorWeightFstImpl : public CacheImpl<Arc> {
       return unfactored_[element.state];
     } else {
       const auto insert_result =
-          element_map_.insert(std::make_pair(element, elements_.size()));
+          element_map_.emplace(element, elements_.size());
       if (insert_result.second) {
         elements_.push_back(element);
       }
index 289b628..aba5217 100644 (file)
@@ -65,8 +65,6 @@ class IntegerFilterState {
 
   T GetState() const { return state_; }
 
-  void SetState(T state) { state_ = state; }
-
  private:
   T state_;
 };
@@ -97,8 +95,6 @@ class WeightFilterState {
 
   W GetWeight() const { return weight_; }
 
-  void SetWeight(W weight) { weight_ = std::move(weight); }
-
  private:
   W weight_;
 };
@@ -128,8 +124,6 @@ class ListFilterState {
 
   std::forward_list<T> *GetMutableState() { return &list_; }
 
-  void SetState(const std::forward_list<T> &state) { list_ = state; }
-
  private:
   std::forward_list<T> list_;
 };
@@ -138,9 +132,13 @@ class ListFilterState {
 template <class FS1, class FS2>
 class PairFilterState {
  public:
+  using FilterState1 = FS1;
+  using FilterState2 = FS2;
+
   PairFilterState() : fs1_(FS1::NoState()), fs2_(FS2::NoState()) {}
 
-  PairFilterState(const FS1 &fs1, const FS2 &fs2) : fs1_(fs1), fs2_(fs2) {}
+  PairFilterState(const FilterState1 &fs1, const FilterState2 &fs2)
+      : fs1_(fs1), fs2_(fs2) {}
 
   static const PairFilterState NoState() { return PairFilterState(); }
 
@@ -159,18 +157,13 @@ class PairFilterState {
     return fs1_ != fs.fs1_ || fs2_ != fs.fs2_;
   }
 
-  const FS1 &GetState1() const { return fs1_; }
-
-  const FS2 &GetState2() const { return fs2_; }
+  const FilterState1 &GetState1() const { return fs1_; }
 
-  void SetState(const FS1 &fs1, const FS2 &fs2) {
-    fs1_ = fs1;
-    fs2_ = fs2;
-  }
+  const FilterState2 &GetState2() const { return fs2_; }
 
  private:
-  FS1 fs1_;
-  FS2 fs2_;
+  FilterState1 fs1_;
+  FilterState2 fs2_;
 };
 
 // Single non-blocking filter state.
index c5e5a7e..07866d6 100644 (file)
@@ -29,8 +29,6 @@
 #include <fst/types.h>
 #include <fst/lock.h>
 
-using std::string;
-
 // FLAGS USAGE:
 //
 // Definition example:
@@ -49,7 +47,7 @@ using std::string;
 // ShowUsage() can be used to print out command and flag usage.
 
 #define DECLARE_bool(name) extern bool FLAGS_ ## name
-#define DECLARE_string(name) extern string FLAGS_ ## name
+#define DECLARE_string(name) extern std::string FLAGS_##name
 #define DECLARE_int32(name) extern int32 FLAGS_ ## name
 #define DECLARE_int64(name) extern int64 FLAGS_ ## name
 #define DECLARE_double(name) extern double FLAGS_ ## name
@@ -57,7 +55,7 @@ using std::string;
 template <typename T>
 struct FlagDescription {
   FlagDescription(T *addr, const char *doc, const char *type,
-                 const char *file, const T val)
+                  const char *file, const T val)
       : address(addr),
     doc_string(doc),
     type_name(type),
@@ -79,19 +77,18 @@ class FlagRegister {
     return reg;
   }
 
-  const FlagDescription<T> &GetFlagDescription(const string &name) const {
+  const FlagDescription<T> &GetFlagDescription(const std::string &name) const {
     fst::MutexLock l(&flag_lock_);
     auto it = flag_table_.find(name);
     return it != flag_table_.end() ? it->second : 0;
   }
 
-  void SetDescription(const string &name,
-                      const FlagDescription<T> &desc) {
+  void SetDescription(const std::string &name, const FlagDescription<T> &desc) {
     fst::MutexLock l(&flag_lock_);
     flag_table_.insert(make_pair(name, desc));
   }
 
-  bool SetFlag(const string &val, bool *address) const {
+  bool SetFlag(const std::string &val, bool *address) const {
     if (val == "true" || val == "1" || val.empty()) {
       *address = true;
       return true;
@@ -104,47 +101,45 @@ class FlagRegister {
     }
   }
 
-  bool SetFlag(const string &val, string *address) const {
+  bool SetFlag(const std::string &val, std::string *address) const {
     *address = val;
     return true;
   }
 
-  bool SetFlag(const string &val, int32 *address) const {
+  bool SetFlag(const std::string &val, int32 *address) const {
     char *p = 0;
     *address = strtol(val.c_str(), &p, 0);
     return !val.empty() && *p == '\0';
   }
 
-  bool SetFlag(const string &val, int64 *address) const {
+  bool SetFlag(const std::string &val, int64 *address) const {
     char *p = 0;
     *address = strtoll(val.c_str(), &p, 0);
     return !val.empty() && *p == '\0';
   }
 
-  bool SetFlag(const string &val, double *address) const {
+  bool SetFlag(const std::string &val, double *address) const {
     char *p = 0;
     *address = strtod(val.c_str(), &p);
     return !val.empty() && *p == '\0';
   }
 
-  bool SetFlag(const string &arg, const string &val) const {
-    for (typename std::map< string, FlagDescription<T> >::const_iterator it =
-           flag_table_.begin();
-         it != flag_table_.end();
-         ++it) {
-      const string &name = it->first;
-      const FlagDescription<T> &desc = it->second;
+  bool SetFlag(const std::string &arg, const std::string &val) const {
+    for (const auto &kv : flag_table_) {
+      const std::string &name = kv.first;
+      const FlagDescription<T> &desc = kv.second;
       if (arg == name)
         return SetFlag(val, desc.address);
     }
     return false;
   }
 
-  void GetUsage(std::set<std::pair<string, string>> *usage_set) const {
+  void GetUsage(
+      std::set<std::pair<std::string, std::string>> *usage_set) const {
     for (auto it = flag_table_.begin(); it != flag_table_.end(); ++it) {
-      const string &name = it->first;
+      const std::string &name = it->first;
       const FlagDescription<T> &desc = it->second;
-      string usage = "  --" + name;
+      std::string usage = "  --" + name;
       usage += ": type = ";
       usage += desc.type_name;
       usage += ", default = ";
@@ -155,29 +150,29 @@ class FlagRegister {
   }
 
  private:
-  string GetDefault(bool default_value) const {
+  std::string GetDefault(bool default_value) const {
     return default_value ? "true" : "false";
   }
 
-  string GetDefault(const string &default_value) const {
+  std::string GetDefault(const std::string &default_value) const {
     return "\"" + default_value + "\"";
   }
 
   template <class V>
-  string GetDefault(const V &default_value) const {
+  std::string GetDefault(const V &default_value) const {
     std::ostringstream strm;
     strm << default_value;
     return strm.str();
   }
 
   mutable fst::Mutex flag_lock_;        // Multithreading lock.
-  std::map<string, FlagDescription<T>> flag_table_;
+  std::map<std::string, FlagDescription<T>> flag_table_;
 };
 
 template <typename T>
 class FlagRegisterer {
  public:
-  FlagRegisterer(const string &name, const FlagDescription<T> &desc) {
+  FlagRegisterer(const std::string &name, const FlagDescription<T> &desc) {
     auto registr = FlagRegister<T>::GetRegister();
     registr->SetDescription(name, desc);
   }
@@ -199,7 +194,7 @@ class FlagRegisterer {
 
 #define DEFINE_bool(name, value, doc) DEFINE_VAR(bool, name, value, doc)
 #define DEFINE_string(name, value, doc) \
-  DEFINE_VAR(string, name, value, doc)
+  DEFINE_VAR(std::string, name, value, doc)
 #define DEFINE_int32(name, value, doc) DEFINE_VAR(int32, name, value, doc)
 #define DEFINE_int64(name, value, doc) DEFINE_VAR(int64, name, value, doc)
 #define DEFINE_double(name, value, doc) DEFINE_VAR(double, name, value, doc)
index 8fade68..54cba33 100644 (file)
@@ -158,7 +158,7 @@ inline std::ostream &operator<<(std::ostream &strm,
 
 template <class T>
 inline std::istream &operator>>(std::istream &strm, FloatWeightTpl<T> &w) {
-  string s;
+  std::string s;
   strm >> s;
   if (s == "Infinity") {
     w = FloatWeightTpl<T>(FloatLimits<T>::PosInfinity());
@@ -197,10 +197,9 @@ class TropicalWeightTpl : public FloatWeightTpl<T> {
     return Limits::NumberBad();
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(string("tropical") +
-                   FloatWeightTpl<T>::GetPrecisionString());
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
+        std::string("tropical") + FloatWeightTpl<T>::GetPrecisionString());
     return *type;
   }
 
@@ -416,9 +415,9 @@ class LogWeightTpl : public FloatWeightTpl<T> {
 
   static constexpr LogWeightTpl NoWeight() { return Limits::NumberBad(); }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(string("log") + FloatWeightTpl<T>::GetPrecisionString());
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
+        std::string("log") + FloatWeightTpl<T>::GetPrecisionString());
     return *type;
   }
 
@@ -637,9 +636,9 @@ class MinMaxWeightTpl : public FloatWeightTpl<T> {
 
   static constexpr MinMaxWeightTpl NoWeight() { return Limits::NumberBad(); }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(string("minmax") + FloatWeightTpl<T>::GetPrecisionString());
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
+        std::string("minmax") + FloatWeightTpl<T>::GetPrecisionString());
     return *type;
   }
 
index 6b9af03..2f2acd5 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_FST_DECL_H_
 
 #include <sys/types.h>
+
 #include <memory>  // for allocator<>
 
 #include <fst/types.h>
index 20e6bb3..d9fb408 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <cmath>
 #include <cstddef>
-
 #include <iostream>
 #include <memory>
 #include <sstream>
@@ -35,7 +34,7 @@ DECLARE_bool(fst_align);
 
 namespace fst {
 
-bool IsFstHeader(std::istream &, const string &);
+bool IsFstHeader(std::istream &, const std::string &);
 
 class FstHeader;
 
@@ -54,7 +53,7 @@ struct FstReadOptions {
   // a warning indicating why it was chosen.
   enum FileReadMode { READ, MAP };
 
-  string source;                // Where you're reading from.
+  std::string source;           // Where you're reading from.
   const FstHeader *header;      // Pointer to FST header; if non-zero, use
                                 // this info (don't read a stream header).
   const SymbolTable *isymbols;  // Pointer to input symbols; if non-zero, use
@@ -65,30 +64,31 @@ struct FstReadOptions {
   bool read_isymbols;           // Read isymbols, if any (default: true).
   bool read_osymbols;           // Read osymbols, if any (default: true).
 
-  explicit FstReadOptions(const string &source = "<unspecified>",
+  explicit FstReadOptions(const std::string &source = "<unspecified>",
                           const FstHeader *header = nullptr,
                           const SymbolTable *isymbols = nullptr,
                           const SymbolTable *osymbols = nullptr);
 
-  explicit FstReadOptions(const string &source, const SymbolTable *isymbols,
+  explicit FstReadOptions(const std::string &source,
+                          const SymbolTable *isymbols,
                           const SymbolTable *osymbols = nullptr);
 
   // Helper function to convert strings FileReadModes into their enum value.
-  static FileReadMode ReadMode(const string &mode);
+  static FileReadMode ReadMode(const std::string &mode);
 
   // Outputs a debug string for the FstReadOptions object.
-  string DebugString() const;
+  std::string DebugString() const;
 };
 
 struct FstWriteOptions {
-  string source;        // Where you're writing to.
+  std::string source;   // Where you're writing to.
   bool write_header;    // Write the header?
   bool write_isymbols;  // Write input symbols?
   bool write_osymbols;  // Write output symbols?
   bool align;           // Write data aligned (may fail on pipes)?
   bool stream_write;    // Avoid seek operations in writing.
 
-  explicit FstWriteOptions(const string &source = "<unspecifed>",
+  explicit FstWriteOptions(const std::string &source = "<unspecifed>",
                            bool write_header = true, bool write_isymbols = true,
                            bool write_osymbols = true,
                            bool align = FLAGS_fst_align,
@@ -107,22 +107,22 @@ struct FstWriteOptions {
 
 class FstHeader {
  public:
-  enum {
+  enum Flags {
     HAS_ISYMBOLS = 0x1,  // Has input symbol table.
     HAS_OSYMBOLS = 0x2,  // Has output symbol table.
     IS_ALIGNED = 0x4,    // Memory-aligned (where appropriate).
-  } Flags;
+  };
 
   FstHeader() : version_(0), flags_(0), properties_(0), start_(-1),
       numstates_(0), numarcs_(0) {}
 
-  const string &FstType() const { return fsttype_; }
+  const std::string &FstType() const { return fsttype_; }
 
-  const string &ArcType() const { return arctype_; }
+  const std::string &ArcType() const { return arctype_; }
 
   int32 Version() const { return version_; }
 
-  int32 GetFlags() const { return flags_; }
+  uint32 GetFlags() const { return flags_; }
 
   uint64 Properties() const { return properties_; }
 
@@ -132,13 +132,13 @@ class FstHeader {
 
   int64 NumArcs() const { return numarcs_; }
 
-  void SetFstType(const string &type) { fsttype_ = type; }
+  void SetFstType(const std::string &type) { fsttype_ = type; }
 
-  void SetArcType(const string &type) { arctype_ = type; }
+  void SetArcType(const std::string &type) { arctype_ = type; }
 
   void SetVersion(int32 version) { version_ = version; }
 
-  void SetFlags(int32 flags) { flags_ = flags; }
+  void SetFlags(uint32 flags) { flags_ = flags; }
 
   void SetProperties(uint64 properties) { properties_ = properties; }
 
@@ -148,23 +148,22 @@ class FstHeader {
 
   void SetNumArcs(int64 numarcs) { numarcs_ = numarcs; }
 
-  bool Read(std::istream &strm, const string &source,
-            bool rewind = false);
+  bool Read(std::istream &strm, const std::string &source, bool rewind = false);
 
-  bool Write(std::ostream &strm, const string &source) const;
+  bool Write(std::ostream &strm, const std::string &source) const;
 
   // Outputs a debug string for the FstHeader object.
-  string DebugString() const;
+  std::string DebugString() const;
 
  private:
-  string fsttype_;     // E.g. "vector".
-  string arctype_;     // E.g. "standard".
-  int32 version_;      // Type version number.
-  int32 flags_;        // File format bits.
-  uint64 properties_;  // FST property bits.
-  int64 start_;        // Start state.
-  int64 numstates_;    // # of states.
-  int64 numarcs_;      // # of arcs.
+  std::string fsttype_;  // E.g. "vector".
+  std::string arctype_;  // E.g. "standard".
+  int32 version_;        // Type version number.
+  uint32 flags_;         // File format bits.
+  uint64 properties_;    // FST property bits.
+  int64 start_;          // Start state.
+  int64 numstates_;      // # of states.
+  int64 numarcs_;        // # of arcs.
 };
 
 // Specifies matcher action.
@@ -212,7 +211,7 @@ class Fst {
   virtual uint64 Properties(uint64 mask, bool test) const = 0;
 
   // FST type name.
-  virtual const string &Type() const = 0;
+  virtual const std::string &Type() const = 0;
 
   // Gets a copy of this Fst. The copying behaves as follows:
   //
@@ -252,7 +251,7 @@ class Fst {
 
   // Reads an FST from a file; returns nullptr on error. An empty filename
   // results in reading from standard input.
-  static Fst<Arc> *Read(const string &filename) {
+  static Fst<Arc> *Read(const std::string &filename) {
     if (!filename.empty()) {
       std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
@@ -275,7 +274,7 @@ class Fst {
 
   // Writes an FST to a file; returns false on error; an empty filename
   // results in writing to standard output.
-  virtual bool Write(const string &filename) const {
+  virtual bool Write(const std::string &filename) const {
     LOG(ERROR) << "Fst::Write: No write filename method for " << Type()
                << " FST type";
     return false;
@@ -300,17 +299,19 @@ class Fst {
   virtual MatcherBase<Arc> *InitMatcher(MatchType match_type) const;
 
  protected:
-  bool WriteFile(const string &filename) const {
+  bool WriteFile(const std::string &filename) const {
     if (!filename.empty()) {
       std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
-        LOG(ERROR) << "Fst::Write: Can't open file: " << filename;
+        LOG(ERROR) << "Fst::WriteFile: Can't open file: " << filename;
+        return false;
+      }
+      if (!Write(strm, FstWriteOptions(filename))) {
+        LOG(ERROR) << "Fst::WriteFile: Write failed: " << filename;
         return false;
       }
-      bool val = Write(strm, FstWriteOptions(filename));
-      if (!val) LOG(ERROR) << "Fst::Write failed: " << filename;
-      return val;
+      return true;
     } else {
       return Write(std::cout, FstWriteOptions("standard output"));
     }
@@ -659,9 +660,9 @@ class FstImpl {
 
   FstImpl &operator=(FstImpl<Arc> &&impl) noexcept;
 
-  const string &Type() const { return type_; }
+  const std::string &Type() const { return type_; }
 
-  void SetType(const string &type) { type_ = type; }
+  void SetType(const std::string &type) { type_ = type; }
 
   virtual uint64 Properties() const { return properties_; }
 
@@ -739,7 +740,7 @@ class FstImpl {
   // cross-type serialization methods Fst::WriteFst.
   static void WriteFstHeader(const Fst<Arc> &fst, std::ostream &strm,
                              const FstWriteOptions &opts, int version,
-                             const string &type, uint64 properties,
+                             const std::string &type, uint64 properties,
                              FstHeader *hdr) {
     if (opts.write_header) {
       hdr->SetFstType(type);
@@ -772,7 +773,7 @@ class FstImpl {
   // success, false on failure.
   static bool UpdateFstHeader(const Fst<Arc> &fst, std::ostream &strm,
                               const FstWriteOptions &opts, int version,
-                              const string &type, uint64 properties,
+                              const std::string &type, uint64 properties,
                               FstHeader *hdr, size_t header_offset) {
     strm.seekp(header_offset);
     if (!strm) {
@@ -796,7 +797,7 @@ class FstImpl {
   mutable uint64 properties_;  // Property bits.
 
  private:
-  string type_;  // Unique name of FST class.
+  std::string type_;  // Unique name of FST class.
   std::unique_ptr<SymbolTable> isymbols_;
   std::unique_ptr<SymbolTable> osymbols_;
 };
@@ -816,13 +817,11 @@ bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
   } else if (!hdr->Read(strm, opts.source)) {
     return false;
   }
-  if (FLAGS_v >= 2) {
-    LOG(INFO) << "FstImpl::ReadHeader: source: " << opts.source
-              << ", fst_type: " << hdr->FstType()
-              << ", arc_type: " << Arc::Type()
-              << ", version: " << hdr->Version()
-              << ", flags: " << hdr->GetFlags();
-  }
+  VLOG(2) << "FstImpl::ReadHeader: source: " << opts.source
+          << ", fst_type: " << hdr->FstType()
+          << ", arc_type: " << Arc::Type()
+          << ", version: " << hdr->Version()
+          << ", flags: " << hdr->GetFlags();
   if (hdr->FstType() != type_) {
     LOG(ERROR) << "FstImpl::ReadHeader: FST not of type " << type_
                << ": " << opts.source;
@@ -896,7 +895,7 @@ class ImplToFst : public FST {
     }
   }
 
-  const string &Type() const override { return impl_->Type(); }
+  const std::string &Type() const override { return impl_->Type(); }
 
   const SymbolTable *InputSymbols() const override {
     return impl_->InputSymbols();
@@ -977,27 +976,27 @@ void Cast(const IFST &ifst, OFST *ofst) {
 // FST serialization.
 
 template <class Arc>
-string FstToString(const Fst<Arc> &fst,
-                   const FstWriteOptions &options =
-                       FstWriteOptions("FstToString")) {
+std::string FstToString(
+    const Fst<Arc> &fst,
+    const FstWriteOptions &options = FstWriteOptions("FstToString")) {
   std::ostringstream ostrm;
   fst.Write(ostrm, options);
   return ostrm.str();
 }
 
 template <class Arc>
-void FstToString(const Fst<Arc> &fst, string *result) {
+void FstToString(const Fst<Arc> &fst, std::string *result) {
   *result = FstToString(fst);
 }
 
 template <class Arc>
-void FstToString(const Fst<Arc> &fst, string *result,
+void FstToString(const Fst<Arc> &fst, std::string *result,
                  const FstWriteOptions &options) {
   *result = FstToString(fst, options);
 }
 
 template <class Arc>
-Fst<Arc> *StringToFst(const string &s) {
+Fst<Arc> *StringToFst(const std::string &s) {
   std::istringstream istrm(s);
   return Fst<Arc>::Read(istrm, FstReadOptions("StringToFst"));
 }
index ea6b8fe..1c27d40 100644 (file)
@@ -44,7 +44,7 @@ class GenericRegister {
 
   void SetEntry(const KeyType &key, const EntryType &entry) {
     MutexLock l(&register_lock_);
-    register_table_.insert(std::make_pair(key, entry));
+    register_table_.emplace(key, entry);
   }
 
   EntryType GetEntry(const KeyType &key) const {
@@ -88,7 +88,7 @@ class GenericRegister {
   }
 
   // Override this to define how to turn a key into an SO filename.
-  virtual string ConvertKeyToSoFilename(const KeyType &key) const = 0;
+  virtual std::string ConvertKeyToSoFilename(const KeyType &key) const = 0;
 
   virtual const EntryType *LookupEntry(const KeyType &key) const {
     MutexLock l(&register_lock_);
index 5459da2..a682922 100644 (file)
@@ -21,7 +21,7 @@ namespace fst {
 // if necessary. It is possible to use this sensibly with as little as 8 bits
 // of Label precision. This returns `true` deterministically for compatibility.
 template <class Label>
-bool ByteStringToLabels(const string &str, std::vector<Label> *labels) {
+bool ByteStringToLabels(const std::string &str, std::vector<Label> *labels) {
   for (const unsigned char ch : str) labels->push_back(ch);
   return true;
 }
@@ -33,7 +33,7 @@ bool ByteStringToLabels(const string &str, std::vector<Label> *labels) {
 // from the various Astral Planes. Naturally, it is safe to use this with larger
 // Labels (e.g., 64 bits).
 template <class Label>
-bool UTF8StringToLabels(const string &str, std::vector<Label> *labels) {
+bool UTF8StringToLabels(const std::string &str, std::vector<Label> *labels) {
   for (auto it = str.begin(); it != str.end();) {
     int c = *it & 0xff;
     ++it;
@@ -73,7 +73,7 @@ bool UTF8StringToLabels(const string &str, std::vector<Label> *labels) {
 }
 
 template <class Label>
-bool LabelsToByteString(const std::vector<Label> &labels, string *str) {
+bool LabelsToByteString(const std::vector<Label> &labels, std::string *str) {
   std::ostringstream ostrm;
   for (const char label : labels) {
     if (label != 0) ostrm << label;
@@ -83,7 +83,7 @@ bool LabelsToByteString(const std::vector<Label> &labels, string *str) {
 }
 
 template <class Label>
-bool LabelsToUTF8String(const std::vector<Label> &labels, string *str) {
+bool LabelsToUTF8String(const std::vector<Label> &labels, std::string *str) {
   std::ostringstream ostrm;
   for (const int32 label : labels) {
     if (label < 0) {
index b100b0a..c97206d 100644 (file)
@@ -3,13 +3,14 @@
 //
 // Function to test two FSTs are isomorphic, i.e., they are equal up to a state
 // and arc re-ordering. FSTs should be deterministic when viewed as
-// unweighted automata.
+// unweighted automata. False negatives (but not false positives) are possible
+// when the inputs are nondeterministic (when viewed as unweighted automata).
 
 #ifndef FST_ISOMORPHIC_H_
 #define FST_ISOMORPHIC_H_
 
 #include <algorithm>
-#include <list>
+#include <queue>
 #include <type_traits>
 #include <vector>
 
 namespace fst {
 namespace internal {
 
-// Orders weights for equality checking.
+// Orders weights for equality checking; delta is ignored.
 template <class Weight, typename std::enable_if<
                             IsIdempotent<Weight>::value>::type * = nullptr>
-bool WeightCompare(const Weight &w1, const Weight &w2, float delta,
-                   bool *error) {
-  return NaturalLess<Weight>()(w1, w2);
+bool WeightCompare(const Weight &w1, const Weight &w2, float, bool *) {
+  static const NaturalLess<Weight> less;
+  return less(w1, w2);
 }
 
 template <class Weight, typename std::enable_if<
@@ -36,8 +37,8 @@ bool WeightCompare(const Weight &w1, const Weight &w2, float delta,
   // No natural order; use hash.
   const auto q1 = w1.Quantize(delta);
   const auto q2 = w2.Quantize(delta);
-  auto n1 = q1.Hash();
-  auto n2 = q2.Hash();
+  const auto n1 = q1.Hash();
+  const auto n2 = q2.Hash();
   // Hash not unique; very unlikely to happen.
   if (n1 == n2 && q1 != q2) {
     VLOG(1) << "Isomorphic: Weight hash collision";
@@ -56,6 +57,7 @@ class Isomorphism {
         fst2_(fst2.Copy()),
         delta_(delta),
         error_(false),
+        nondet_(false),
         comp_(delta, &error_) {}
 
   // Checks if input FSTs are isomorphic.
@@ -64,13 +66,21 @@ class Isomorphism {
       return true;
     }
     if (fst1_->Start() == kNoStateId || fst2_->Start() == kNoStateId) {
+      VLOG(1) << "Isomorphic: Only one of the FSTs is empty.";
       return false;
     }
     PairState(fst1_->Start(), fst2_->Start());
     while (!queue_.empty()) {
       const auto &pr = queue_.front();
-      if (!IsIsomorphicState(pr.first, pr.second)) return false;
-      queue_.pop_front();
+      if (!IsIsomorphicState(pr.first, pr.second)) {
+        if (nondet_) {
+          VLOG(1) << "Isomorphic: Non-determinism as an unweighted automaton. "
+                  << "state1: " << pr.first << " state2: " << pr.second;
+          error_ = true;
+        }
+        return false;
+      }
+      queue_.pop();
     }
     return true;
   }
@@ -88,11 +98,15 @@ class Isomorphism {
       if (arc1.ilabel > arc2.ilabel) return false;
       if (arc1.olabel < arc2.olabel) return true;
       if (arc1.olabel > arc2.olabel) return false;
-      return WeightCompare(arc1.weight, arc2.weight, delta_, error_);
+      if (!ApproxEqual(arc1.weight, arc2.weight, delta_)) {
+        return WeightCompare(arc1.weight, arc2.weight, delta_, error_);
+      } else {
+        return arc1.nextstate < arc2.nextstate;
+      }
     }
 
    private:
-    float delta_;
+    const float delta_;
     bool *error_;
   };
 
@@ -100,16 +114,17 @@ class Isomorphism {
   bool PairState(StateId s1, StateId s2) {
     if (state_pairs_.size() <= s1) state_pairs_.resize(s1 + 1, kNoStateId);
     if (state_pairs_[s1] == s2) {
-      return true;  // already seen this pair
+      return true;  // Already seen this pair.
     } else if (state_pairs_[s1] != kNoStateId) {
-      return false;  // s1 already paired with another s2
+      return false;  // s1 already paired with another s2.
     }
+    VLOG(3) << "Pairing states: (" << s1 << ", " << s2 << ")";
     state_pairs_[s1] = s2;
-    queue_.push_back(std::make_pair(s1, s2));
+    queue_.emplace(s1, s2);
     return true;
   }
 
-  // Checks if state pair is isomorphic
+  // Checks if state pair is isomorphic.
   bool IsIsomorphicState(StateId s1, StateId s2);
 
   std::unique_ptr<Fst<Arc>> fst1_;
@@ -118,17 +133,23 @@ class Isomorphism {
   std::vector<Arc> arcs1_;               // For sorting arcs on FST1.
   std::vector<Arc> arcs2_;               // For sorting arcs on FST2.
   std::vector<StateId> state_pairs_;     // Maintains state correspondences.
-  std::list<std::pair<StateId, StateId>> queue_;  // Queue of state pairs.
+  std::queue<std::pair<StateId, StateId>> queue_;  // Queue of state pairs.
   bool error_;                           // Error flag.
+  bool nondet_;                          // Nondeterminism detected.
   ArcCompare comp_;
 };
 
 template <class Arc>
 bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
   if (!ApproxEqual(fst1_->Final(s1), fst2_->Final(s2), delta_)) return false;
-  auto narcs1 = fst1_->NumArcs(s1);
-  auto narcs2 = fst2_->NumArcs(s2);
-  if (narcs1 != narcs2) return false;
+  const auto narcs1 = fst1_->NumArcs(s1);
+  const auto narcs2 = fst2_->NumArcs(s2);
+  if (narcs1 != narcs2) {
+    VLOG(1) << "Isomorphic: NumArcs not equal. "
+            << "fst1.NumArcs(" << s1 << ") = " << narcs1 << ", "
+            << "fst2.NumArcs(" << s2 << ") = " << narcs2;
+    return false;
+  }
   ArcIterator<Fst<Arc>> aiter1(*fst1_, s1);
   ArcIterator<Fst<Arc>> aiter2(*fst2_, s2);
   arcs1_.clear();
@@ -144,17 +165,52 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
   for (size_t i = 0; i < arcs1_.size(); ++i) {
     const auto &arc1 = arcs1_[i];
     const auto &arc2 = arcs2_[i];
-    if (arc1.ilabel != arc2.ilabel) return false;
-    if (arc1.olabel != arc2.olabel) return false;
-    if (!ApproxEqual(arc1.weight, arc2.weight, delta_)) return false;
-    if (!PairState(arc1.nextstate, arc2.nextstate)) return false;
+    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;
+      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;
+      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;
+      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 << "*";
+      return false;
+    }
     if (i > 0) {  // Checks for non-determinism.
       const auto &arc0 = arcs1_[i - 1];
       if (arc1.ilabel == arc0.ilabel && arc1.olabel == arc0.olabel &&
           ApproxEqual(arc1.weight, arc0.weight, delta_)) {
-        VLOG(1) << "Isomorphic: Non-determinism as an unweighted automaton";
-        error_ = true;
-        return false;
+        // Any subsequent matching failure maybe a false negative
+        // since we only consider one permutation when pairing destination
+        // 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
+                << " " << arc2.weight << " " << arc2.nextstate;
+        nondet_ = true;
       }
     }
   }
@@ -164,12 +220,16 @@ 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 non-deterministic when viewed as unweighted automata.
+// Inputs should be nondeterministic 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
+// false negatives (but it never returns false positives).
 template <class Arc>
 bool Isomorphic(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
                 float delta = kDelta) {
   internal::Isomorphism<Arc> iso(fst1, fst2, delta);
-  bool result = iso.IsIsomorphic();
+  const bool result = iso.IsIsomorphic();
   if (iso.Error()) {
     FSTERROR() << "Isomorphic: Cannot determine if inputs are isomorphic";
     return false;
index f3d7f2b..b52e7b8 100644 (file)
@@ -218,7 +218,7 @@ class LabelReachable {
     // Maps labels to their new values in [1, label2index().size()].
     for (auto it = label2index.begin(); it != label2index.end(); ++it) {
       if (it->second != data_->FinalLabel()) {
-        pairs->push_back(std::make_pair(it->first, it->second));
+        pairs->emplace_back(it->first, it->second);
       }
     }
     if (avoid_collisions) {
@@ -227,7 +227,7 @@ class LabelReachable {
       for (size_t i = 1; i <= label2index.size(); ++i) {
         const auto it = label2index.find(i);
         if (it == label2index.end() || it->second == data_->FinalLabel()) {
-          pairs->push_back(std::make_pair(i, label2index.size() + 1));
+          pairs->emplace_back(i, label2index.size() + 1);
         }
       }
     }
@@ -387,7 +387,7 @@ class LabelReachable {
         auto arc = aiter.Value();
         const auto label = data_->ReachInput() ? arc.ilabel : arc.olabel;
         if (label) {
-          auto insert_result = label2state_.insert(std::make_pair(label, ons));
+          auto insert_result = label2state_.emplace(label, ons);
           if (insert_result.second) {
             indeg.push_back(0);
             ++ons;
@@ -400,7 +400,7 @@ class LabelReachable {
       // Redirects final weights to new final state.
       auto final_weight = fst_->Final(s);
       if (final_weight != Weight::Zero()) {
-        auto insert_result = label2state_.insert(std::make_pair(kNoLabel, ons));
+        auto insert_result = label2state_.emplace(kNoLabel, ons);
         if (insert_result.second) {
           indeg.push_back(0);
           ++ons;
@@ -415,15 +415,13 @@ class LabelReachable {
     // Adds new final states to the FST.
     while (fst_->NumStates() < ons) {
       StateId s = fst_->AddState();
-      fst_->SetFinal(s, Weight::One());
+      fst_->SetFinal(s);
     }
     // Creates a super-initial state for all states with zero in-degree.
     const auto start = fst_->AddState();
     fst_->SetStart(start);
     for (StateId s = 0; s < start; ++s) {
-      if (indeg[s] == 0) {
-        fst_->EmplaceArc(start, 0, 0, Weight::One(), s);
-      }
+      if (indeg[s] == 0) fst_->EmplaceArc(start, 0, 0, s);
     }
   }
 
index af3c6db..5f02664 100644 (file)
@@ -14,7 +14,6 @@
 #define FST_LEXICOGRAPHIC_WEIGHT_H_
 
 #include <cstdlib>
-
 #include <string>
 
 #include <fst/log.h>
@@ -74,9 +73,9 @@ class LexicographicWeight : public PairWeight<W1, W2> {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(W1::Type() + "_LT_" + W2::Type());
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string(W1::Type() + "_LT_" + W2::Type());
     return *type;
   }
 
index 388d42f..2a3f9ea 100644 (file)
 #ifndef FST_LIB_LOCK_H_
 #define FST_LIB_LOCK_H_
 
-#include <mutex>
+#ifdef OPENFST_HAS_ABSL
+
+#include "absl/synchronization/mutex.h"
 
 namespace fst {
 
-using namespace std;
+using absl::Mutex;
+using absl::MutexLock;
+using absl::ReaderMutexLock;
+
+}  // namespace fst
+
+#else  // OPENFST_HAS_ABSL
+
+#include <mutex>
+
+namespace fst {
 
 class Mutex {
  public:
@@ -59,4 +71,6 @@ using ReaderMutexLock = MutexLock;
 
 }  // namespace fst
 
+#endif  // OPENFST_HAS_ABSL
+
 #endif  // FST_LIB_LOCK_H_
index 0a8d6d7..b777a16 100644 (file)
 #include <fst/types.h>
 #include <fst/flags.h>
 
-using std::string;
-
 DECLARE_int32(v);
 
 class LogMessage {
  public:
-  LogMessage(const string &type) : fatal_(type == "FATAL") {
+  LogMessage(const std::string &type) : fatal_(type == "FATAL") {
     std::cerr << type << ": ";
   }
   ~LogMessage() {
index d542cfe..c529fef 100644 (file)
@@ -687,6 +687,9 @@ inline LabelLookAheadRelabeler<Arc, Data>::LabelLookAheadRelabeler(
   const bool is_mutable = fst.Properties(kMutable, false);
   std::unique_ptr<MutableFst<Arc>> mfst;
   if (is_mutable) {
+    // 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));
   } else {
     mfst.reset(new VectorFst<Arc>(fst));
@@ -708,7 +711,10 @@ inline LabelLookAheadRelabeler<Arc, Data>::LabelLookAheadRelabeler(
       WriteLabelPairs(FLAGS_save_relabel_opairs, pairs);
     }
   }
-  if (!is_mutable) {
+  if (is_mutable) {
+    // Pointer was just borrowed, don't delete it.
+    mfst.release();
+  } else {
     *impl = std::make_shared<Impl>(*mfst, name);
     (*impl)->SetAddOn(data);
   }
index adb33c2..eadfdb1 100644 (file)
@@ -24,7 +24,7 @@ struct MemoryRegion {
   void *data;
   void *mmap;
   size_t size;
-  int offset;
+  size_t offset;
 };
 
 class MappedFile {
@@ -41,19 +41,19 @@ class MappedFile {
   // source argument needs to contain the filename that was used to open the
   // input stream.
   static MappedFile *Map(std::istream *istrm, bool memorymap,
-                         const string &source, size_t size);
+                         const std::string &source, size_t size);
 
   // Returns a MappedFile object that contains the contents of the file referred
   // to by the file descriptor starting from pos with size bytes. If the
   // memory mapping fails, nullptr is returned. In contrast to Map(), this
   // factory function does not backoff to allocating and reading.
-  static MappedFile *MapFromFileDescriptor(int fd, int pos, size_t size);
+  static MappedFile *MapFromFileDescriptor(int fd, size_t pos, size_t size);
 
   // Creates a MappedFile object with a new[]'ed block of memory of size. The
   // align argument can be used to specify a desired block alignment.
   // This is RECOMMENDED FOR INTERNAL USE ONLY as it may change in future
   // releases.
-  static MappedFile *Allocate(size_t size, int align = kArchAlignment);
+  static MappedFile *Allocate(size_t size, size_t align = kArchAlignment);
 
   // Creates a MappedFile object pointing to a borrowed reference to data. This
   // block of memory is not owned by the MappedFile object and will not be
@@ -65,7 +65,7 @@ class MappedFile {
   // are not aligned upon a 128-bit boundary are read from the file instead.
   // This is consistent with the alignment boundary set in ConstFst and
   // CompactFst.
-  static constexpr int kArchAlignment = 16;
+  static constexpr size_t kArchAlignment = 16;
 
   static constexpr size_t kMaxReadChunk = 256 * 1024 * 1024;  // 256 MB.
 
index 61e9582..a8b63c1 100644 (file)
@@ -114,7 +114,7 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
   // Read a MatcherFst from a file; return nullptr on error
   // Empty filename reads from standard input
   static MatcherFst<FST, FstMatcher, Name, Init, Data> *Read(
-      const string &filename) {
+      const std::string &filename) {
     auto *impl = ImplToExpandedFst<Impl>::Read(filename);
     return impl ? new MatcherFst<FST, FstMatcher, Name, Init, Data>(
                       std::shared_ptr<Impl>(impl))
@@ -125,7 +125,7 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
     return GetImpl()->Write(strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<Arc>::WriteFile(filename);
   }
 
@@ -164,7 +164,7 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
   using ImplToFst<Impl, ExpandedFst<Arc>>::GetImpl;
 
   static std::shared_ptr<Impl> CreateDataAndImpl(const FST &fst,
-                                                 const string &name) {
+                                                 const std::string &name) {
     FstMatcher imatcher(fst, MATCH_INPUT);
     FstMatcher omatcher(fst, MATCH_OUTPUT);
     return CreateImpl(fst, name,
@@ -173,12 +173,13 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
   }
 
   static std::shared_ptr<Impl> CreateDataAndImpl(const Fst<Arc> &fst,
-                                                 const string &name) {
+                                                 const std::string &name) {
     FST result(fst);
     return CreateDataAndImpl(result, name);
   }
 
-  static std::shared_ptr<Impl> CreateImpl(const FST &fst, const string &name,
+  static std::shared_ptr<Impl> CreateImpl(const FST &fst,
+                                          const std::string &name,
                                           std::shared_ptr<Data> data) {
     auto impl = std::make_shared<Impl>(fst, name);
     impl->SetAddOn(data);
index 9f17a22..34f283c 100644 (file)
@@ -6,9 +6,8 @@
 #ifndef FST_MINIMIZE_H_
 #define FST_MINIMIZE_H_
 
-#include <cmath>
-
 #include <algorithm>
+#include <cmath>
 #include <map>
 #include <queue>
 #include <utility>
@@ -196,7 +195,7 @@ class CyclicMinimizer {
             (fst.Final(s) != Weight::Zero() ? hash_to_class_final
                                             : hash_to_class_nonfinal);
         // Avoids two map lookups by using 'insert' instead of 'find'.
-        auto p = this_map.insert(std::make_pair(hash, next_class));
+        auto p = this_map.emplace(hash, next_class);
         state_to_initial_class[s] = p.second ? next_class++ : p.first->second;
       }
       // Lets the unordered_maps go out of scope before we allocate the classes,
@@ -387,8 +386,7 @@ class AcyclicMinimizer {
       PartitionIterator<StateId> siter(partition_, h);
       equiv_classes[siter.Value()] = h;
       for (siter.Next(); !siter.Done(); siter.Next()) {
-        auto insert_result =
-            equiv_classes.insert(std::make_pair(siter.Value(), kNoStateId));
+        auto insert_result = equiv_classes.emplace(siter.Value(), kNoStateId);
         if (insert_result.second) {
           insert_result.first->second = partition_.AddClass();
         }
index 9031770..3ec7817 100644 (file)
@@ -7,9 +7,9 @@
 #ifndef FST_MUTABLE_FST_H_
 #define FST_MUTABLE_FST_H_
 
-#include <stddef.h>
 #include <sys/types.h>
 
+#include <cstddef>
 #include <istream>
 #include <string>
 #include <utility>
@@ -45,7 +45,7 @@ class MutableFst : public ExpandedFst<A> {
   virtual void SetStart(StateId) = 0;
 
   // Sets a state's final weight.
-  virtual void SetFinal(StateId, Weight) = 0;
+  virtual void SetFinal(StateId s, Weight weight = Weight::One()) = 0;
 
   // Sets property bits w.r.t. mask.
   virtual void SetProperties(uint64 props, uint64 mask) = 0;
@@ -53,8 +53,11 @@ class MutableFst : public ExpandedFst<A> {
   // Adds a state and returns its ID.
   virtual StateId AddState() = 0;
 
+  // Adds multiple states.
+  virtual void AddStates(size_t) = 0;
+
   // Adds an arc to state.
-  virtual void AddArc(StateId, const Arc &arc) = 0;
+  virtual void AddArc(StateId, const Arc &) = 0;
 
   // Adds an arc (passed by rvalue reference) to state. Allows subclasses
   // to optionally implement move semantics. Defaults to lvalue overload.
@@ -67,16 +70,16 @@ class MutableFst : public ExpandedFst<A> {
   virtual void DeleteStates() = 0;
 
   // Delete some arcs at a given state.
-  virtual void DeleteArcs(StateId, size_t n) = 0;
+  virtual void DeleteArcs(StateId, size_t) = 0;
 
   // Delete all arcs at a given state.
   virtual void DeleteArcs(StateId) = 0;
 
   // Optional, best effort only.
-  virtual void ReserveStates(StateId n) {}
+  virtual void ReserveStates(size_t) {}
 
   // Optional, best effort only.
-  virtual void ReserveArcs(StateId s, size_t n) {}
+  virtual void ReserveArcs(StateId, size_t) {}
 
   // Returns input label symbol table or nullptr if not specified.
   const SymbolTable *InputSymbols() const override = 0;
@@ -129,8 +132,9 @@ class MutableFst : public ExpandedFst<A> {
   // filename results in reading from standard input. If convert is true,
   // convert to a mutable FST subclass (given by convert_type) in the case
   // that the input FST is non-mutable.
-  static MutableFst<Arc> *Read(const string &filename, bool convert = false,
-                               const string &convert_type = "vector") {
+  static MutableFst<Arc> *Read(const std::string &filename,
+                               bool convert = false,
+                               const std::string &convert_type = "vector") {
     if (convert == false) {
       if (!filename.empty()) {
         std::ifstream strm(filename,
@@ -282,7 +286,7 @@ class ImplToMutableFst : public ImplToExpandedFst<Impl, FST> {
     GetMutableImpl()->SetStart(s);
   }
 
-  void SetFinal(StateId s, Weight weight) override {
+  void SetFinal(StateId s, Weight weight = Weight::One()) override {
     MutateCheck();
     GetMutableImpl()->SetFinal(s, std::move(weight));
   }
@@ -300,6 +304,11 @@ class ImplToMutableFst : public ImplToExpandedFst<Impl, FST> {
     return GetMutableImpl()->AddState();
   }
 
+  void AddStates(size_t n) override {
+    MutateCheck();
+    return GetMutableImpl()->AddStates(n);
+  }
+
   void AddArc(StateId s, const Arc &arc) override {
     MutateCheck();
     GetMutableImpl()->AddArc(s, arc);
@@ -307,7 +316,7 @@ class ImplToMutableFst : public ImplToExpandedFst<Impl, FST> {
 
   void AddArc(StateId s, Arc &&arc) override {
     MutateCheck();
-    GetMutableImpl()->AddArc(s, std::move(arc));
+    GetMutableImpl()->AddArc(s, std::forward<Arc>(arc));
   }
 
   void DeleteStates(const std::vector<StateId> &dstates) override {
@@ -337,9 +346,9 @@ class ImplToMutableFst : public ImplToExpandedFst<Impl, FST> {
     GetMutableImpl()->DeleteArcs(s);
   }
 
-  void ReserveStates(StateId s) override {
+  void ReserveStates(size_t n) override {
     MutateCheck();
-    GetMutableImpl()->ReserveStates(s);
+    GetMutableImpl()->ReserveStates(n);
   }
 
   void ReserveArcs(StateId s, size_t n) override {
diff --git a/src/include/fst/power-weight-mappers.h b/src/include/fst/power-weight-mappers.h
new file mode 100644 (file)
index 0000000..15fb9e9
--- /dev/null
@@ -0,0 +1,97 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
+// Conversions to/from PowerWeight and SparsePowerWeight.
+
+#ifndef FST_POWER_WEIGHT_MAPPERS_H_
+#define FST_POWER_WEIGHT_MAPPERS_H_
+
+namespace fst {
+
+// Converts FromWeight to ToPowerWeight (with one component).
+// ToPowerWeight may be PowerWeight or SparsePowerWeight.
+template <class FromWeight_, class ToPowerWeight>
+class ToPowerWeightMapper {
+ public:
+  using FromWeight = FromWeight_;
+  using ToWeight = ToPowerWeight;
+  using Index = typename ToPowerWeight::Index;
+
+  explicit ToPowerWeightMapper(Index index = 0) : index_(index) {}
+
+  ToPowerWeight operator()(const FromWeight &w) const {
+    return ToPowerWeight(index_, w.Value());
+  }
+
+ private:
+  const Index index_;
+};
+
+// Converts FromPowerWeight to ToWeight. Uses only one component.
+// FromPowerWeight may be PowerWeight or SparsePowerWeight.
+template <class FromPowerWeight, class ToWeight_>
+class FromPowerWeightMapper {
+ public:
+  using FromWeight = FromPowerWeight;
+  using ToWeight = ToWeight_;
+  using Index = typename FromPowerWeight::Index;
+
+  explicit FromPowerWeightMapper(Index index = 0) : index_(index) {}
+
+  ToWeight operator()(const FromPowerWeight &w) const {
+    return ToWeight(w.Value(index_));
+  }
+
+ private:
+  const Index index_;
+};
+
+// Projects to one dimension of the weight vector, filling the indices
+// with `default_weight`.
+// PowerWeightT may be PowerWeight or SparsePowerWeight.
+template <class PowerWeightT>
+class ProjectPowerWeightMapper {
+ public:
+  using FromWeight = PowerWeightT;
+  using ToWeight = PowerWeightT;
+  using Index = typename PowerWeightT::Index;
+  using ComponentWeight = typename PowerWeightT::Weight;
+
+  explicit ProjectPowerWeightMapper(
+      Index from_index = 0, Index to_index = 0,
+      const ComponentWeight &default_weight = ComponentWeight::Zero())
+    : from_index_(from_index), to_index_(to_index),
+      default_weight_(default_weight) {}
+
+  PowerWeightT operator()(const PowerWeightT &w) const {
+    return PowerWeightT(to_index_, w.Value(from_index_), default_weight_);
+  }
+
+ private:
+  const Index from_index_;
+  const Index to_index_;
+  const ComponentWeight default_weight_;
+};
+
+// Applies a transformation function to each weight vector.
+// PowerWeightT may be PowerWeight or SparsePowerWeight.
+template <class PowerWeightT, class TransformFn_>
+class TransformPowerWeightMapper {
+ public:
+  using TransformFn = TransformFn_;
+  using FromWeight = PowerWeightT;
+  using ToWeight = PowerWeightT;
+
+  explicit TransformPowerWeightMapper(
+      const TransformFn &transform = TransformFn())
+      : transform_(transform) {}
+
+  PowerWeightT operator()(const PowerWeightT &w) const { return transform_(w); }
+
+ private:
+  TransformFn transform_;
+};
+
+}  // namespace fst
+
+#endif  // FST_POWER_WEIGHT_MAPPERS_H_
index f2f3cbd..86ecb22 100644 (file)
@@ -57,9 +57,9 @@ class PowerWeight : public TupleWeight<W, n> {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(W::Type() + "_^" + std::to_string(n));
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string(W::Type() + "_^" + std::to_string(n));
     return *type;
   }
 
index 56a18be..dc57d66 100644 (file)
@@ -45,9 +45,9 @@ class ProductWeight : public PairWeight<W1, W2> {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string(W1::Type() + "_X_" + W2::Type());
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string(W1::Type() + "_X_" + W2::Type());
     return *type;
   }
 
index 157247a..d974700 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_PROPERTIES_H_
 
 #include <sys/types.h>
+
 #include <vector>
 
 #include <fst/compat.h>
@@ -119,10 +120,10 @@ constexpr uint64 kString = 0x0000100000000000ULL;
 // Not a string FST.
 constexpr uint64 kNotString = 0x0000200000000000ULL;
 
-// FST has least one weighted cycle.
+// FST has at least one weighted cycle.
 constexpr uint64 kWeightedCycles = 0x0000400000000000ULL;
 
-// Only unweighted cycles.
+// FST has no weighted cycles. Any cycles that may be present are unweighted.
 constexpr uint64 kUnweightedCycles = 0x0000800000000000ULL;
 
 // COMPOSITE PROPERTIES
@@ -134,6 +135,12 @@ constexpr uint64 kNullProperties =
     kInitialAcyclic | kTopSorted | kAccessible | kCoAccessible | kString |
     kUnweightedCycles;
 
+// Properties of a string FST compiled into a string.
+constexpr uint64 kCompiledStringProperties =
+    kAcceptor | kString | kUnweighted | kIDeterministic | kODeterministic |
+    kILabelSorted | kOLabelSorted | kAcyclic | kInitialAcyclic |
+    kUnweightedCycles | kTopSorted | kAccessible | kCoAccessible;
+
 // Properties that are preserved when an FST is copied.
 constexpr uint64 kCopyProperties =
     kError | kAcceptor | kNotAcceptor | kIDeterministic | kNonIDeterministic |
index f57d176..bbe1a44 100644 (file)
@@ -231,6 +231,8 @@ class ShortestFirstQueue : public QueueBase<S> {
     if (update) key_.clear();
   }
 
+  ssize_t Size() const { return heap_.Size(); }
+
   const Compare &GetCompare() const { return heap_.GetCompare(); }
 
  private:
@@ -312,10 +314,11 @@ class PruneNaturalShortestFirstQueue
   using StateId = S;
   using Base = NaturalShortestFirstQueue<StateId, Weight>;
 
-  explicit PruneNaturalShortestFirstQueue(const std::vector<Weight> &distance,
-                                          int threshold)
+  PruneNaturalShortestFirstQueue(const std::vector<Weight> &distance,
+                                 ssize_t arc_threshold, ssize_t state_limit = 0)
       : Base(distance),
-        threshold_(threshold),
+        arc_threshold_(arc_threshold),
+        state_limit_(state_limit),
         head_steps_(0),
         max_head_steps_(0) {}
 
@@ -341,7 +344,22 @@ class PruneNaturalShortestFirstQueue
     }
     // This is the number of arcs in the minimum cost path from Start to s.
     steps_[s] = state_steps;
-    if (state_steps > (max_head_steps_ - threshold_) || threshold_ < 0) {
+
+    // Adjust the threshold in cases where path step thresholding wasn't
+    // enough to keep the queue small.
+    ssize_t adjusted_threshold = arc_threshold_;
+    if (Base::Size() > state_limit_ && state_limit_ > 0) {
+      adjusted_threshold = std::max<ssize_t>(
+          0, arc_threshold_ - (Base::Size() / state_limit_) - 1);
+    }
+
+    if (state_steps > (max_head_steps_ - adjusted_threshold) ||
+        arc_threshold_ < 0) {
+      if (adjusted_threshold == 0 && state_limit_ > 0) {
+        // If the queue is continuing to grow without bound, we follow any
+        // path that makes progress and clear the rest.
+        Base::Clear();
+      }
       Base::Enqueue(s);
     }
   }
@@ -352,7 +370,10 @@ class PruneNaturalShortestFirstQueue
   std::vector<ssize_t> steps_;
   // We only keep paths that are within this number of arcs (not weight!)
   // of the longest path.
-  const ssize_t threshold_;
+  const ssize_t arc_threshold_;
+  // If the size of the queue climbs above this number, we increase the
+  // threshold to reduce the amount of work we have to do.
+  const ssize_t state_limit_;
 
   // The following are mutable because Head() is const.
   // The number of arcs traversed in the minimum cost path from the start
index 5bcd9fd..30c0e0d 100644 (file)
@@ -6,8 +6,8 @@
 #ifndef FST_RANDGEN_H_
 #define FST_RANDGEN_H_
 
-#include <math.h>
-#include <stddef.h>
+#include <cmath>
+#include <cstddef>
 #include <limits>
 #include <map>
 #include <memory>
@@ -498,7 +498,7 @@ class RandGenFstImpl : public CacheImpl<ToArc> {
   // states as needed.
   void Expand(StateId s) {
     if (s == superfinal_) {
-      SetFinal(s, ToWeight::One());
+      SetFinal(s);
       SetArcs(s);
       return;
     }
@@ -535,9 +535,7 @@ class RandGenFstImpl : public CacheImpl<ToArc> {
             state_table_.emplace_back(
                 new RandState<FromArc>(kNoStateId, 0, 0, 0, nullptr));
           }
-          for (size_t n = 0; n < count; ++n) {
-            EmplaceArc(s, 0, 0, ToWeight::One(), superfinal_);
-          }
+          for (size_t n = 0; n < count; ++n) EmplaceArc(s, 0, 0, superfinal_);
         }
       }
     }
@@ -711,7 +709,7 @@ class RandGenVisitor {
       ofst_->AddArc(src, arc);
       src = dest;
     }
-    ofst_->SetFinal(src, Weight::One());
+    ofst_->SetFinal(src);
   }
 
   const Fst<FromArc> *ifst_;
index 184ebf3..29e9f40 100644 (file)
@@ -113,7 +113,7 @@ class RationalFstImpl : public FstImpl<A> {
     rfst_.AddState();
     rfst_.AddState();
     rfst_.SetStart(0);
-    rfst_.SetFinal(1, Weight::One());
+    rfst_.SetFinal(1);
     rfst_.SetInputSymbols(fst1.InputSymbols());
     rfst_.SetOutputSymbols(fst1.OutputSymbols());
     nonterminals_ = 2;
@@ -135,7 +135,7 @@ class RationalFstImpl : public FstImpl<A> {
     rfst_.AddState();
     rfst_.AddState();
     rfst_.SetStart(0);
-    rfst_.SetFinal(2, Weight::One());
+    rfst_.SetFinal(2);
     rfst_.SetInputSymbols(fst1.InputSymbols());
     rfst_.SetOutputSymbols(fst1.OutputSymbols());
     nonterminals_ = 2;
@@ -155,13 +155,13 @@ class RationalFstImpl : public FstImpl<A> {
     if (closure_type == CLOSURE_STAR) {
       rfst_.AddState();
       rfst_.SetStart(0);
-      rfst_.SetFinal(0, Weight::One());
+      rfst_.SetFinal(0);
       rfst_.EmplaceArc(0, 0, -1, Weight::One(), 0);
     } else {
       rfst_.AddState();
       rfst_.AddState();
       rfst_.SetStart(0);
-      rfst_.SetFinal(1, Weight::One());
+      rfst_.SetFinal(1);
       rfst_.EmplaceArc(0, 0, -1, Weight::One(), 1);
       rfst_.EmplaceArc(1, 0, 0, Weight::One(), 0);
     }
@@ -182,7 +182,7 @@ class RationalFstImpl : public FstImpl<A> {
     afst.AddState();
     afst.AddState();
     afst.SetStart(0);
-    afst.SetFinal(1, Weight::One());
+    afst.SetFinal(1);
     ++nonterminals_;
     afst.EmplaceArc(0, 0, -nonterminals_, Weight::One(), 1);
     Union(&rfst_, afst);
@@ -199,7 +199,7 @@ class RationalFstImpl : public FstImpl<A> {
     afst.AddState();
     afst.AddState();
     afst.SetStart(0);
-    afst.SetFinal(1, Weight::One());
+    afst.SetFinal(1);
     ++nonterminals_;
     afst.EmplaceArc(0, 0, -nonterminals_, Weight::One(), 1);
     if (append) {
index 2d1a6ea..4dcfb72 100644 (file)
@@ -42,23 +42,23 @@ struct FstRegisterEntry {
 // This class maintains the correspondence between a string describing
 // an FST type, and its reader and converter.
 template <class Arc>
-class FstRegister
-    : public GenericRegister<string, FstRegisterEntry<Arc>, FstRegister<Arc>> {
+class FstRegister : public GenericRegister<std::string, FstRegisterEntry<Arc>,
+                                           FstRegister<Arc>> {
  public:
   using Reader = typename FstRegisterEntry<Arc>::Reader;
   using Converter = typename FstRegisterEntry<Arc>::Converter;
 
-  const Reader GetReader(const string &type) const {
+  const Reader GetReader(const std::string &type) const {
     return this->GetEntry(type).reader;
   }
 
-  const Converter GetConverter(const string &type) const {
+  const Converter GetConverter(const std::string &type) const {
     return this->GetEntry(type).converter;
   }
 
  protected:
-  string ConvertKeyToSoFilename(const string &key) const override {
-    string legal_type(key);
+  std::string ConvertKeyToSoFilename(const std::string &key) const override {
+    std::string legal_type(key);
     ConvertToLegalCSymbol(&legal_type);
     return legal_type + "-fst.so";
   }
@@ -99,7 +99,7 @@ class FstRegisterer : public GenericRegisterer<FstRegister<typename FST::Arc>> {
 
 // Converts an FST to the specified type.
 template <class Arc>
-Fst<Arc> *Convert(const Fst<Arc> &fst, const string &fst_type) {
+Fst<Arc> *Convert(const Fst<Arc> &fst, const std::string &fst_type) {
   auto *reg = FstRegister<Arc>::GetRegister();
   const auto converter = reg->GetConverter(fst_type);
   if (!converter) {
index 0979b07..b863289 100644 (file)
@@ -78,11 +78,11 @@ void Relabel(
 // FST. If the 'unknown_i(o)symbol' is non-empty, it is used to label any
 // missing symbol in new_i(o)symbols table.
 template <class Arc>
-void Relabel(MutableFst<Arc> *fst,
-             const SymbolTable *old_isymbols, const SymbolTable *new_isymbols,
-             const string &unknown_isymbol, bool attach_new_isymbols,
+void Relabel(MutableFst<Arc> *fst, const SymbolTable *old_isymbols,
+             const SymbolTable *new_isymbols,
+             const std::string &unknown_isymbol, bool attach_new_isymbols,
              const SymbolTable *old_osymbols, const SymbolTable *new_osymbols,
-             const string &unknown_osymbol, bool attach_new_osymbols) {
+             const std::string &unknown_osymbol, bool attach_new_osymbols) {
   using Label = typename Arc::Label;
   // Constructs vectors of input-side label pairs.
   std::vector<std::pair<Label, Label>> ipairs;
@@ -112,7 +112,7 @@ void Relabel(MutableFst<Arc> *fst,
           ++num_missing_syms;
         }
       }
-      ipairs.push_back(std::make_pair(old_index, new_index));
+      ipairs.emplace_back(old_index, new_index);
     }
     if (num_missing_syms > 0) {
       LOG(WARNING) << "Target symbol table missing: " << num_missing_syms
@@ -133,7 +133,6 @@ void Relabel(MutableFst<Arc> *fst,
         ++num_missing_syms;
       }
     }
-
     for (SymbolTableIterator siter(*old_osymbols); !siter.Done();
          siter.Next()) {
       const auto old_index = siter.Value();
@@ -148,7 +147,7 @@ void Relabel(MutableFst<Arc> *fst,
           ++num_missing_syms;
         }
       }
-      opairs.push_back(std::make_pair(old_index, new_index));
+      opairs.emplace_back(old_index, new_index);
     }
     if (num_missing_syms > 0) {
       LOG(WARNING) << "Target symbol table missing: " << num_missing_syms
index 42c6982..0e26b08 100644 (file)
@@ -9,6 +9,7 @@
 #include <map>
 #include <unordered_map>
 #include <unordered_set>
+#include <utility>
 #include <vector>
 
 #include <fst/log.h>
@@ -325,36 +326,36 @@ void ReplaceUtil<Arc>::GetDependencies(bool stats) const {
   }
   have_stats_ = stats;
   if (have_stats_) stats_.reserve(fst_array_.size());
-  for (Label i = 0; i < fst_array_.size(); ++i) {
+  for (Label ilabel = 0; ilabel < fst_array_.size(); ++ilabel) {
     depfst_.AddState();
-    depfst_.SetFinal(i, Weight::One());
+    depfst_.SetFinal(ilabel);
     if (have_stats_) stats_.push_back(ReplaceStats());
   }
   depfst_.SetStart(root_fst_);
   // An arc from each state (representing the FST) to the state representing the
   // FST being replaced
-  for (Label i = 0; i < fst_array_.size(); ++i) {
-    const auto *ifst = fst_array_[i];
+  for (Label ilabel = 0; ilabel < fst_array_.size(); ++ilabel) {
+    const auto *ifst = fst_array_[ilabel];
     if (!ifst) continue;
     for (StateIterator<Fst<Arc>> siter(*ifst); !siter.Done(); siter.Next()) {
       const auto s = siter.Value();
       if (have_stats_) {
-        ++stats_[i].nstates;
-        if (ifst->Final(s) != Weight::Zero()) ++stats_[i].nfinal;
+        ++stats_[ilabel].nstates;
+        if (ifst->Final(s) != Weight::Zero()) ++stats_[ilabel].nfinal;
       }
       for (ArcIterator<Fst<Arc>> aiter(*ifst, s); !aiter.Done();
            aiter.Next()) {
-        if (have_stats_) ++stats_[i].narcs;
+        if (have_stats_) ++stats_[ilabel].narcs;
         const auto &arc = aiter.Value();
         auto it = nonterminal_hash_.find(arc.olabel);
         if (it != nonterminal_hash_.end()) {
-          const auto j = it->second;
-          depfst_.EmplaceArc(i, arc.olabel, arc.olabel, Weight::One(), j);
+          const auto nextstate = it->second;
+          depfst_.EmplaceArc(ilabel, arc.olabel, arc.olabel, nextstate);
           if (have_stats_) {
-            ++stats_[i].nnonterms;
-            ++stats_[j].nref;
-            ++stats_[j].inref[i];
-            ++stats_[i].outref[j];
+            ++stats_[ilabel].nnonterms;
+            ++stats_[nextstate].nref;
+            ++stats_[nextstate].inref[ilabel];
+            ++stats_[ilabel].outref[nextstate];
           }
         }
       }
@@ -492,12 +493,12 @@ void ReplaceUtil<Arc>::ReplaceLabels(const std::vector<Label> &labels) {
       const auto &arc = aiter.Value();
       const auto label = nonterminal_array_[arc.nextstate];
       const auto *fst = fst_array_[arc.nextstate];
-      fst_pairs.push_back(std::make_pair(label, fst));
+      fst_pairs.emplace_back(label, fst);
     }
     if (fst_pairs.empty()) continue;
     const auto label = nonterminal_array_[s];
     const auto *fst = fst_array_[s];
-    fst_pairs.push_back(std::make_pair(label, fst));
+    fst_pairs.emplace_back(label, fst);
     const ReplaceUtilOptions opts(label, call_label_type_, return_label_type_,
                                   return_label_);
     Replace(fst_pairs, mutable_fst_array_[s], opts);
@@ -553,7 +554,7 @@ void ReplaceUtil<Arc>::GetFstPairs(std::vector<FstPair> *fst_pairs) {
     const auto label = nonterminal_array_[i];
     const auto *fst = fst_array_[i];
     if (!fst) continue;
-    fst_pairs->push_back(std::make_pair(label, fst));
+    fst_pairs->emplace_back(label, fst);
   }
 }
 
@@ -566,7 +567,7 @@ void ReplaceUtil<Arc>::GetMutableFstPairs(
     const auto label = nonterminal_array_[i];
     const auto *fst = mutable_fst_array_[i];
     if (!fst) continue;
-    mutable_fst_pairs->push_back(std::make_pair(label, fst->Copy()));
+    mutable_fst_pairs->emplace_back(label, fst->Copy());
   }
 }
 
index 7c7c89d..78614aa 100644 (file)
@@ -32,8 +32,7 @@ template <class FromArc, class ToArc>
 void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
              bool require_superinitial = true) {
   using StateId = typename FromArc::StateId;
-  using FromWeight = typename FromArc::Weight;
-  using ToWeight = typename ToArc::Weight;
+  using Weight = typename FromArc::Weight;
   ofst->DeleteStates();
   ofst->SetInputSymbols(ifst.InputSymbols());
   ofst->SetOutputSymbols(ifst.OutputSymbols());
@@ -48,7 +47,7 @@ void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
   if (!require_superinitial) {
     for (StateIterator<Fst<FromArc>> siter(ifst); !siter.Done(); siter.Next()) {
       const auto s = siter.Value();
-      if (ifst.Final(s) == FromWeight::Zero()) continue;
+      if (ifst.Final(s) == Weight::Zero()) continue;
       if (ostart != kNoStateId) {
         ostart = kNoStateId;
         break;
@@ -56,7 +55,7 @@ void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
         ostart = s;
       }
     }
-    if (ostart != kNoStateId && ifst.Final(ostart) != FromWeight::One()) {
+    if (ostart != kNoStateId && ifst.Final(ostart) != Weight::One()) {
       std::vector<StateId> scc;
       SccVisitor<FromArc> scc_visitor(&scc, nullptr, nullptr, &dfs_iprops);
       DfsVisit(ifst, &scc_visitor);
@@ -82,9 +81,9 @@ void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
     const auto is = siter.Value();
     const auto os = is + offset;
     while (ofst->NumStates() <= os) ofst->AddState();
-    if (is == istart) ofst->SetFinal(os, ToWeight::One());
+    if (is == istart) ofst->SetFinal(os);
     const auto weight = ifst.Final(is);
-    if ((weight != FromWeight::Zero()) && (offset == 1)) {
+    if ((weight != Weight::Zero()) && (offset == 1)) {
       const ToArc oarc(0, 0, weight.Reverse(), os);
       ofst->AddArc(0, oarc);
     }
index 64e68cb..af8aa12 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_REWEIGHT_H_
 
 #include <vector>
+
 #include <fst/log.h>
 
 #include <fst/mutable-fst.h>
index 5135bf2..70e512c 100644 (file)
@@ -153,8 +153,8 @@ void RmEpsilonState<Arc, Queue>::Expand(typename Arc::StateId source) {
         if (!visited_[arc.nextstate]) eps_queue_.push(arc.nextstate);
       } else {
         const Element element(arc.ilabel, arc.olabel, arc.nextstate);
-        auto insert_result = element_map_.insert(
-            std::make_pair(element, std::make_pair(expand_id_, arcs_.size())));
+        auto insert_result = element_map_.emplace(
+            element, std::make_pair(expand_id_, arcs_.size()));
         if (insert_result.second) {
           arcs_.push_back(std::move(arc));
         } else {
index 8e4ca4f..e509eb2 100644 (file)
@@ -106,7 +106,7 @@ class ArcIteratorClass {
 
 template <class Arc>
 void InitArcIteratorClass(InitArcIteratorClassArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   std::get<2>(*args)->impl_.reset(
       new ArcIteratorClassImpl<Arc>(fst, std::get<1>(*args)));
 }
index 943a0b7..42ea82f 100644 (file)
@@ -36,10 +36,10 @@ 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 string &source,  // NOLINT
+  FstCompiler(std::istream &istrm, const std::string &source,  // NOLINT
               const SymbolTable *isyms, const SymbolTable *osyms,
-              const SymbolTable *ssyms, bool accep, bool ikeep,
-              bool okeep, bool nkeep, bool allow_negative_labels = false) {
+              const SymbolTable *ssyms, bool accep, bool ikeep, bool okeep,
+              bool nkeep, bool allow_negative_labels = false) {
     std::unique_ptr<SymbolTable> misyms(isyms ? isyms->Copy() : nullptr);
     std::unique_ptr<SymbolTable> mosyms(osyms ? osyms->Copy() : nullptr);
     std::unique_ptr<SymbolTable> mssyms(ssyms ? ssyms->Copy() : nullptr);
@@ -47,7 +47,7 @@ class FstCompiler {
          ikeep, okeep, nkeep, allow_negative_labels, false);
   }
 
-  FstCompiler(std::istream &istrm, const string &source,  // NOLINT
+  FstCompiler(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) {
@@ -55,7 +55,7 @@ class FstCompiler {
          allow_negative_labels, add_symbols);
   }
 
-  void Init(std::istream &istrm, const string &source,  // NOLINT
+  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) {
@@ -70,7 +70,7 @@ class FstCompiler {
     add_symbols_ = add_symbols;
     bool start_state_populated = false;
     char line[kLineLen];
-    const string separator = FLAGS_fst_field_separator + "\n";
+    const std::string separator = FLAGS_fst_field_separator + "\n";
     while (istrm.getline(line, kLineLen)) {
       ++nline_;
       std::vector<char *> col;
@@ -198,7 +198,7 @@ class FstCompiler {
 
   mutable VectorFst<Arc> fst_;
   size_t nline_;
-  string source_;       // Text FST source name.
+  std::string source_;  // Text FST source name.
   SymbolTable *isyms_;  // ilabel symbol table (not owned).
   SymbolTable *osyms_;  // olabel symbol table (not owned).
   SymbolTable *ssyms_;  // slabel symbol table (not owned).
index c82ed47..c588f8e 100644 (file)
@@ -25,8 +25,8 @@ namespace script {
 // for anything else!
 struct CompileFstInnerArgs {
   std::istream &istrm;
-  const string &source;
-  const string &fst_type;
+  const std::string &source;
+  const std::string &fst_type;
   const fst::SymbolTable *isyms;
   const fst::SymbolTable *osyms;
   const fst::SymbolTable *ssyms;
@@ -36,8 +36,9 @@ struct CompileFstInnerArgs {
   const bool nkeep;
   const bool allow_negative_labels;
 
-  CompileFstInnerArgs(std::istream &istrm, const string &source,
-                      const string &fst_type, const fst::SymbolTable *isyms,
+  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,
@@ -79,14 +80,15 @@ void CompileFstInternal(CompileFstArgs *args) {
   args->retval = fst ? new FstClass(*fst) : nullptr;
 }
 
-void CompileFst(std::istream &istrm, const string &source, const string &dest,
-                const string &fst_type, const string &arc_type,
-                const SymbolTable *isyms, const SymbolTable *osyms,
-                const SymbolTable *ssyms, bool accep, bool ikeep, bool okeep,
-                bool nkeep, bool allow_negative_labels);
+void CompileFst(std::istream &istrm, const std::string &source,
+                const std::string &dest, 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);
 
-FstClass *CompileFstInternal(std::istream &istrm, const string &source,
-                             const string &fst_type, const string &arc_type,
+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,
index a173580..9ffd604 100644 (file)
@@ -17,8 +17,8 @@ using ComposeArgs = std::tuple<const FstClass &, const FstClass &,
 
 template <class Arc>
 void Compose(ComposeArgs *args) {
-  const Fst<Arc> &ifst1 = *(std::get<0>(*args).GetFst<Arc>());
-  const Fst<Arc> &ifst2 = *(std::get<1>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst1 = *std::get<0>(*args).GetFst<Arc>();
+  const Fst<Arc> &ifst2 = *std::get<1>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<2>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<3>(*args);
   Compose(ifst1, ifst2, ofst, opts);
index 4bf8dc6..05be3f7 100644 (file)
@@ -17,7 +17,7 @@ using ConcatArgs1 = std::pair<MutableFstClass *, const FstClass &>;
 template <class Arc>
 void Concat(ConcatArgs1 *args) {
   MutableFst<Arc> *ofst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const Fst<Arc> &ifst = *(std::get<1>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<1>(*args).GetFst<Arc>();
   Concat(ofst, ifst);
 }
 
@@ -25,7 +25,7 @@ using ConcatArgs2 = std::pair<const FstClass &, MutableFstClass *>;
 
 template <class Arc>
 void Concat(ConcatArgs2 *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   Concat(ifst, ofst);
 }
index 1a6eeaa..f3c03f0 100644 (file)
 namespace fst {
 namespace script {
 
-using ConvertInnerArgs = std::pair<const FstClass &, const string &>;
+using ConvertInnerArgs = std::pair<const FstClass &, const std::string &>;
 
 using ConvertArgs = WithReturnValue<FstClass *, ConvertInnerArgs>;
 
 template <class Arc>
 void Convert(ConvertArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(args->args).GetFst<Arc>());
-  const string &new_type = std::get<1>(args->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;
 }
 
-FstClass *Convert(const FstClass &fst, const string &new_type);
+FstClass *Convert(const FstClass &fst, const std::string &new_type);
 
 }  // namespace script
 }  // namespace fst
index 09f2539..cde2904 100644 (file)
@@ -15,7 +15,7 @@
 namespace fst {
 namespace script {
 
-using DecodeArgs1 = std::pair<MutableFstClass *, const string &>;
+using DecodeArgs1 = std::pair<MutableFstClass *, const std::string &>;
 
 template <class Arc>
 void Decode(DecodeArgs1 *args) {
@@ -39,7 +39,7 @@ void Decode(DecodeArgs2 *args) {
   Decode(fst, encoder);
 }
 
-void Decode(MutableFstClass *fst, const string &coder_fname);
+void Decode(MutableFstClass *fst, const std::string &coder_fname);
 
 void Decode(MutableFstClass *fst, const EncodeMapperClass &encoder);
 
index 383a8fe..183a629 100644 (file)
@@ -40,10 +40,10 @@ using DeterminizeArgs = std::tuple<const FstClass &, MutableFstClass *,
 template <class Arc>
 void Determinize(DeterminizeArgs *args) {
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<2>(*args);
-  const auto weight_threshold = *(opts.weight_threshold.GetWeight<Weight>());
+  const auto weight_threshold = *opts.weight_threshold.GetWeight<Weight>();
   const fst::DeterminizeOptions<Arc> detargs(opts.delta, weight_threshold,
       opts.state_threshold, opts.subsequential_label, opts.det_type,
       opts.increment_subsequential_label);
index 7af6200..c06d0c7 100644 (file)
@@ -18,8 +18,8 @@ using DifferenceArgs = std::tuple<const FstClass &, const FstClass &,
 
 template <class Arc>
 void Difference(DifferenceArgs *args) {
-  const Fst<Arc> &ifst1 = *(std::get<0>(*args).GetFst<Arc>());
-  const Fst<Arc> &ifst2 = *(std::get<1>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst1 = *std::get<0>(*args).GetFst<Arc>();
+  const Fst<Arc> &ifst2 = *std::get<1>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<2>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<3>(*args);
   Difference(ifst1, ifst2, ofst, opts);
index acc1fba..5f892a9 100644 (file)
@@ -35,10 +35,10 @@ using DisambiguateArgs = std::tuple<const FstClass &, MutableFstClass *,
 template <class Arc>
 void Disambiguate(DisambiguateArgs *args) {
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<2>(*args);
-  const auto weight_threshold = *(opts.weight_threshold.GetWeight<Weight>());
+  const auto weight_threshold = *opts.weight_threshold.GetWeight<Weight>();
   const fst::DisambiguateOptions<Arc> disargs(opts.delta, weight_threshold,
                                                   opts.state_threshold,
                                                   opts.subsequential_label);
index f204b2e..ea9a752 100644 (file)
@@ -28,9 +28,10 @@ class FstDrawer {
 
   FstDrawer(const Fst<Arc> &fst, const SymbolTable *isyms,
             const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-            const string &title, float width, float height, bool portrait,
+            const std::string &title, float width, float height, bool portrait,
             bool vertical, float ranksep, float nodesep, int fontsize,
-            int precision, const string &float_format, bool show_weight_one)
+            int precision, const std::string &float_format,
+            bool show_weight_one)
       : fst_(fst),
         isyms_(isyms),
         osyms_(osyms),
@@ -50,7 +51,7 @@ class FstDrawer {
         show_weight_one_(show_weight_one) {}
 
   // Draws FST to an output buffer.
-  void Draw(std::ostream *strm, const string &dest) {
+  void Draw(std::ostream *strm, const std::string &dest) {
     ostrm_ = strm;
     SetStreamState(ostrm_);
     dest_ = dest;
@@ -67,7 +68,7 @@ class FstDrawer {
     PrintString(",");
     Print(height_);
     PrintString("\";\n");
-    if (!dest_.empty()) PrintString("label = \"" + title_ + "\";\n");
+    if (!title_.empty()) PrintString("label = \"" + title_ + "\";\n");
     PrintString("center = 1;\n");
     if (portrait_) {
       PrintString("orientation = Portrait;\n");
@@ -99,12 +100,12 @@ class FstDrawer {
     // O.w. defaults to "g" per standard lib.
   }
 
-  void PrintString(const string &str) const { *ostrm_ << str; }
+  void PrintString(const std::string &str) const { *ostrm_ << str; }
 
-  // Escapes backslash and double quote if these occur in the string. Dot will
-  // not deal gracefully with these if they are not escaped.
-  static string Escape(const string &str) {
-    string ns;
+  // Escapes backslash and double quote if these occur in the string. Dot
+  // will not deal gracefully with these if they are not escaped.
+  static std::string Escape(const std::string &str) {
+    std::string ns;
     for (char c : str) {
       if (c == '\\' || c == '"') ns.push_back('\\');
       ns.push_back(c);
@@ -147,7 +148,7 @@ class FstDrawer {
   void Print(T t) const { *ostrm_ << t; }
 
   template <class T>
-  string ToString(T t) const {
+  std::string ToString(T t) const {
     std::stringstream ss;
     SetStreamState(&ss);
     ss << t;
@@ -204,9 +205,9 @@ class FstDrawer {
   const SymbolTable *ssyms_;  // slabel symbol table.
   bool accep_;                // Print as acceptor when possible.
   std::ostream *ostrm_;       // Drawn FST destination.
-  string dest_;               // Drawn FST destination name.
+  std::string dest_;          // Drawn FST destination name.
 
-  string title_;
+  std::string title_;
   float width_;
   float height_;
   bool portrait_;
@@ -215,7 +216,7 @@ class FstDrawer {
   float nodesep_;
   int fontsize_;
   int precision_;
-  string float_format_;
+  std::string float_format_;
   bool show_weight_one_;
 
   FstDrawer(const FstDrawer &) = delete;
index cb37df1..997c933 100644 (file)
@@ -22,7 +22,7 @@ struct FstDrawerArgs {
   const SymbolTable *osyms;
   const SymbolTable *ssyms;
   const bool accep;
-  const string &title;
+  const std::string &title;
   const float width;
   const float height;
   const bool portrait;
@@ -31,17 +31,18 @@ struct FstDrawerArgs {
   const float nodesep;
   const int fontsize;
   const int precision;
-  const string &float_format;  // NOLINT
+  const std::string &float_format;  // NOLINT
   const bool show_weight_one;
   std::ostream *ostrm;
-  const string &dest;
+  const std::string &dest;
 
   FstDrawerArgs(const FstClass &fst, const SymbolTable *isyms,
                 const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-                const string &title, float width, float height, bool portrait,
-                bool vertical, float ranksep, float nodesep, int fontsize,
-                int precision, const string &float_format,
-                bool show_weight_one, std::ostream *ostrm,  const string &dest)
+                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),
@@ -64,7 +65,7 @@ struct FstDrawerArgs {
 
 template <class Arc>
 void DrawFst(FstDrawerArgs *args) {
-  const Fst<Arc> &fst = *(args->fst.GetFst<Arc>());
+  const Fst<Arc> &fst = *args->fst.GetFst<Arc>();
   FstDrawer<Arc> fstdrawer(fst, args->isyms, args->osyms, args->ssyms,
       args->accep, args->title, args->width, args->height, args->portrait,
       args->vertical, args->ranksep, args->nodesep, args->fontsize,
@@ -74,10 +75,11 @@ void DrawFst(FstDrawerArgs *args) {
 
 void DrawFst(const FstClass &fst, const SymbolTable *isyms,
              const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             const string &title, float width, float height, bool portrait,
+             const std::string &title, float width, float height, bool portrait,
              bool vertical, float ranksep, float nodesep, int fontsize,
-             int precision, const string &float_format, bool show_weight_one,
-             std::ostream *ostrm, const string &dest);
+             int precision, const std::string &float_format,
+             bool show_weight_one, std::ostream *ostrm,
+             const std::string &dest);
 
 }  // namespace script
 }  // namespace fst
index 6a86968..2c26e3b 100644 (file)
 namespace fst {
 namespace script {
 
-using EncodeArgs1 = std::tuple<MutableFstClass *, uint32, bool, const string &>;
+using EncodeArgs1 =
+    std::tuple<MutableFstClass *, uint32, bool, const std::string &>;
 
 template <class Arc>
 void Encode(EncodeArgs1 *args) {
   MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const string &coder_fname = std::get<3>(*args);
+  const std::string &coder_fname = std::get<3>(*args);
   // If true, reuse encode from disk. If false, make a new encoder and just use
   // the filename argument as the destination state.
   std::unique_ptr<EncodeMapper<Arc>> encoder(
@@ -41,7 +42,7 @@ void Encode(EncodeArgs2 *args) {
 }
 
 void Encode(MutableFstClass *fst, uint32 flags, bool reuse_encoder,
-            const string &coder_fname);
+            const std::string &coder_fname);
 
 void Encode(MutableFstClass *fst, EncodeMapperClass *encoder);
 
index b62824f..2ad39b0 100644 (file)
@@ -4,9 +4,9 @@
 #ifndef FST_SCRIPT_ENCODEMAPPER_CLASS_H_
 #define FST_SCRIPT_ENCODEMAPPER_CLASS_H_
 
+#include <iostream>
 #include <memory>
 #include <string>
-#include <iostream>
 
 #include <fst/fstlib.h>
 #include <fst/script/arc-class.h>
@@ -22,7 +22,7 @@ class EncodeMapperImplBase {
  public:
   // Returns an encoded ArcClass.
   virtual ArcClass operator()(const ArcClass &a) = 0;
-  virtual const string &ArcType() const = 0;
+  virtual const std::string &ArcType() const = 0;
   virtual uint32 Flags() const = 0;
   virtual uint64 Properties(uint64 inprops) = 0;
   virtual EncodeType Type() const = 0;
@@ -30,7 +30,7 @@ class EncodeMapperImplBase {
   virtual const SymbolTable *OutputSymbols() const = 0;
   virtual void SetInputSymbols(const SymbolTable *syms) = 0;
   virtual void SetOutputSymbols(const SymbolTable *syms) = 0;
-  virtual const string &WeightType() const = 0;
+  virtual const std::string &WeightType() const = 0;
   virtual ~EncodeMapperImplBase() {}
 };
 
@@ -43,7 +43,7 @@ class EncodeMapperClassImpl : public EncodeMapperImplBase {
 
   ArcClass operator()(const ArcClass &a) final;
 
-  const string &ArcType() const final { return Arc::Type(); }
+  const std::string &ArcType() const final { return Arc::Type(); }
 
   uint32 Flags() const final { return encoder_.Flags(); }
 
@@ -69,7 +69,7 @@ class EncodeMapperClassImpl : public EncodeMapperImplBase {
     encoder_.SetOutputSymbols(syms);
   }
 
-  const string &WeightType() const final { return Arc::Weight::Type(); }
+  const std::string &WeightType() const final { return Arc::Weight::Type(); }
 
   ~EncodeMapperClassImpl() override {}
 
@@ -97,7 +97,7 @@ using InitEncodeMapperClassArgs =
 
 class EncodeMapperClass {
  public:
-  EncodeMapperClass(const string &arc_type, uint32 flags, EncodeType type);
+  EncodeMapperClass(const std::string &arc_type, uint32 flags, EncodeType type);
 
   template <class Arc>
   EncodeMapperClass(uint32 flags, EncodeType type)
@@ -105,7 +105,7 @@ class EncodeMapperClass {
 
   ArcClass operator()(const ArcClass &arc) { return (*impl_)(arc); }
 
-  const string &ArcType() const { return impl_->ArcType(); }
+  const std::string &ArcType() const { return impl_->ArcType(); }
 
   uint32 Flags() const { return impl_->Flags(); }
 
@@ -125,7 +125,7 @@ class EncodeMapperClass {
     impl_->SetOutputSymbols(syms);
   }
 
-  const string &WeightType() const { return impl_->WeightType(); }
+  const std::string &WeightType() const { return impl_->WeightType(); }
 
   template <class Arc>
   friend void InitEncodeMapperClass(InitEncodeMapperClassArgs *args);
index b55fefa..86bc4d9 100644 (file)
@@ -17,7 +17,7 @@ using EpsNormalizeArgs = std::tuple<const FstClass &, MutableFstClass *,
 
 template <class Arc>
 void EpsNormalize(EpsNormalizeArgs *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   EpsNormalize(ifst, ofst, std::get<2>(*args));
 }
index 79ea9aa..18f8b30 100644 (file)
@@ -19,8 +19,8 @@ using EqualArgs = WithReturnValue<bool, EqualInnerArgs>;
 
 template <class Arc>
 void Equal(EqualArgs *args) {
-  const Fst<Arc> &fst1 = *(std::get<0>(args->args).GetFst<Arc>());
-  const Fst<Arc> &fst2 = *(std::get<1>(args->args).GetFst<Arc>());
+  const Fst<Arc> &fst1 = *std::get<0>(args->args).GetFst<Arc>();
+  const Fst<Arc> &fst2 = *std::get<1>(args->args).GetFst<Arc>();
   args->retval = Equal(fst1, fst2, std::get<2>(args->args));
 }
 
index 7cdff45..f3d4f88 100644 (file)
@@ -20,8 +20,8 @@ using EquivalentArgs = WithReturnValue<bool, EquivalentInnerArgs>;
 
 template <class Arc>
 void Equivalent(EquivalentArgs *args) {
-  const Fst<Arc> &fst1 = *(std::get<0>(args->args).GetFst<Arc>());
-  const Fst<Arc> &fst2 = *(std::get<1>(args->args).GetFst<Arc>());
+  const Fst<Arc> &fst1 = *std::get<0>(args->args).GetFst<Arc>();
+  const Fst<Arc> &fst2 = *std::get<1>(args->args).GetFst<Arc>();
   args->retval = Equivalent(fst1, fst2, std::get<2>(args->args));
 }
 
index 07319fc..1d9629e 100644 (file)
@@ -33,9 +33,9 @@ namespace script {
 
 class FstClassBase {
  public:
-  virtual const string &ArcType() const = 0;
+  virtual const std::string &ArcType() const = 0;
   virtual WeightClass Final(int64) const = 0;
-  virtual const string &FstType() const = 0;
+  virtual const std::string &FstType() const = 0;
   virtual const SymbolTable *InputSymbols() const = 0;
   virtual size_t NumArcs(int64) const = 0;
   virtual size_t NumInputEpsilons(int64) const = 0;
@@ -43,10 +43,10 @@ class FstClassBase {
   virtual const SymbolTable *OutputSymbols() const = 0;
   virtual uint64 Properties(uint64, bool) const = 0;
   virtual int64 Start() const = 0;
-  virtual const string &WeightType() const = 0;
+  virtual const std::string &WeightType() const = 0;
   virtual bool ValidStateId(int64) const = 0;
-  virtual bool Write(const string &) const = 0;
-  virtual bool Write(std::ostream &, const string &) const = 0;
+  virtual bool Write(const std::string &) const = 0;
+  virtual bool Write(std::ostream &, const std::string &) const = 0;
   virtual ~FstClassBase() {}
 };
 
@@ -55,6 +55,7 @@ class FstClassImplBase : public FstClassBase {
  public:
   virtual bool AddArc(int64, const ArcClass &) = 0;
   virtual int64 AddState() = 0;
+  virtual void AddStates(size_t) = 0;
   virtual FstClassImplBase *Copy() = 0;
   virtual bool DeleteArcs(int64, size_t) = 0;
   virtual bool DeleteArcs(int64) = 0;
@@ -103,7 +104,12 @@ class FstClassImpl : public FstClassImplBase {
     return static_cast<MutableFst<Arc> *>(impl_.get())->AddState();
   }
 
-  const string &ArcType() const final { return Arc::Type(); }
+  // 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);
+  }
+
+  const std::string &ArcType() const final { return Arc::Type(); }
 
   FstClassImpl *Copy() final { return new FstClassImpl<Arc>(impl_.get()); }
 
@@ -144,7 +150,7 @@ class FstClassImpl : public FstClassImplBase {
     return w;
   }
 
-  const string &FstType() const final { return impl_->Type(); }
+  const std::string &FstType() const final { return impl_->Type(); }
 
   const SymbolTable *InputSymbols() const final {
     return impl_->InputSymbols();
@@ -195,8 +201,8 @@ class FstClassImpl : public FstClassImplBase {
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
-  void ReserveStates(int64 s) final {
-    static_cast<MutableFst<Arc> *>(impl_.get())->ReserveStates(s);
+  void ReserveStates(int64 n) final {
+    static_cast<MutableFst<Arc> *>(impl_.get())->ReserveStates(n);
   }
 
   const SymbolTable *OutputSymbols() const final {
@@ -249,11 +255,13 @@ class FstClassImpl : public FstClassImplBase {
     return true;
   }
 
-  const string &WeightType() const final { return Arc::Weight::Type(); }
+  const std::string &WeightType() const final { return Arc::Weight::Type(); }
 
-  bool Write(const string &fname) const final { return impl_->Write(fname); }
+  bool Write(const std::string &fname) const final {
+    return impl_->Write(fname);
+  }
 
-  bool Write(std::ostream &ostr, const string &fname) const final {
+  bool Write(std::ostream &ostr, const std::string &fname) const final {
     const FstWriteOptions opts(fname);
     return impl_->Write(ostr, opts);
   }
@@ -287,9 +295,9 @@ class FstClass : public FstClassBase {
 
   WeightClass Final(int64 s) const final { return impl_->Final(s); }
 
-  const string &ArcType() const final { return impl_->ArcType(); }
+  const std::string &ArcType() const final { return impl_->ArcType(); }
 
-  const string &FstType() const final { return impl_->FstType(); }
+  const std::string &FstType() const final { return impl_->FstType(); }
 
   const SymbolTable *InputSymbols() const final {
     return impl_->InputSymbols();
@@ -315,24 +323,27 @@ class FstClass : public FstClassBase {
     return impl_->Properties(mask, test);
   }
 
-  static FstClass *Read(const string &fname);
+  static FstClass *Read(const std::string &fname);
 
-  static FstClass *Read(std::istream &istrm, const string &source);
+  static FstClass *Read(std::istream &istrm, const std::string &source);
 
   int64 Start() const final { return impl_->Start(); }
 
   bool ValidStateId(int64 s) const final { return impl_->ValidStateId(s); }
 
-  const string &WeightType() const final { return impl_->WeightType(); }
+  const std::string &WeightType() const final { return impl_->WeightType(); }
 
   // Helper that logs an ERROR if the weight type of an FST and a WeightClass
   // don't match.
 
-  bool WeightTypesMatch(const WeightClass &weight, const string &op_name) const;
+  bool WeightTypesMatch(const WeightClass &weight,
+                        const std::string &op_name) const;
 
-  bool Write(const string &fname) const final { return impl_->Write(fname); }
+  bool Write(const std::string &fname) const final {
+    return impl_->Write(fname);
+  }
 
-  bool Write(std::ostream &ostr, const string &fname) const final {
+  bool Write(std::ostream &ostr, const std::string &fname) const final {
     return impl_->Write(ostr, fname);
   }
 
@@ -410,6 +421,8 @@ class MutableFstClass : public FstClass {
 
   int64 AddState() { return GetImpl()->AddState(); }
 
+  void AddStates(size_t n) { return GetImpl()->AddStates(n); }
+
   bool DeleteArcs(int64 s, size_t n) { return GetImpl()->DeleteArcs(s, n); }
 
   bool DeleteArcs(int64 s) { return GetImpl()->DeleteArcs(s); }
@@ -432,9 +445,9 @@ class MutableFstClass : public FstClass {
 
   bool ReserveArcs(int64 s, size_t n) { return GetImpl()->ReserveArcs(s, n); }
 
-  void ReserveStates(int64 s) { GetImpl()->ReserveStates(s); }
+  void ReserveStates(int64 n) { GetImpl()->ReserveStates(n); }
 
-  static MutableFstClass *Read(const string &fname, bool convert = false);
+  static MutableFstClass *Read(const std::string &fname, bool convert = false);
 
   void SetInputSymbols(SymbolTable *isyms) {
     GetImpl()->SetInputSymbols(isyms);
@@ -498,9 +511,9 @@ class VectorFstClass : public MutableFstClass {
 
   explicit VectorFstClass(const FstClass &other);
 
-  explicit VectorFstClass(const string &arc_type);
+  explicit VectorFstClass(const std::string &arc_type);
 
-  static VectorFstClass *Read(const string &fname);
+  static VectorFstClass *Read(const std::string &fname);
 
   template <class Arc>
   static VectorFstClass *Read(std::istream &stream,
index 5cd727e..b09dc62 100644 (file)
@@ -9,32 +9,31 @@
 
 #include <string>
 
-#include <fst/compose.h>          // For ComposeFilter.
-#include <fst/determinize.h>      // For DeterminizeType.
-#include <fst/encode.h>           // For kEncodeLabels (etc.).
-#include <fst/epsnormalize.h>     // For EpsNormalizeType.
-#include <fst/project.h>          // For ProjectType.
-#include <fst/push.h>             // For kPushWeights (etc.).
-#include <fst/queue.h>            // For QueueType.
-#include <fst/rational.h>         // For ClosureType.
-#include <fst/script/arcsort.h>       // For ArcSortType.
-#include <fst/script/map.h>           // For MapType.
-#include <fst/script/script-impl.h>   // For RandArcSelection.
-
 #include <fst/log.h>
+#include <fst/compose.h>         // For ComposeFilter.
+#include <fst/determinize.h>     // For DeterminizeType.
+#include <fst/encode.h>          // For kEncodeLabels (etc.).
+#include <fst/epsnormalize.h>    // For EpsNormalizeType.
+#include <fst/project.h>         // For ProjectType.
+#include <fst/push.h>            // For kPushWeights (etc.).
+#include <fst/queue.h>           // For QueueType.
+#include <fst/rational.h>        // For ClosureType.
+#include <fst/script/arcsort.h>      // For ArcSortType.
+#include <fst/script/map.h>          // For MapType.
+#include <fst/script/script-impl.h>  // For RandArcSelection.
 
 namespace fst {
 namespace script {
 
-bool GetArcSortType(const string &str, ArcSortType *sort_type);
+bool GetArcSortType(const std::string &str, ArcSortType *sort_type);
 
 inline ClosureType GetClosureType(bool closure_plus) {
   return closure_plus ? CLOSURE_PLUS : CLOSURE_STAR;
 }
 
-bool GetComposeFilter(const string &str, ComposeFilter *compose_filter);
+bool GetComposeFilter(const std::string &str, ComposeFilter *compose_filter);
 
-bool GetDeterminizeType(const string &str, DeterminizeType *det_type);
+bool GetDeterminizeType(const std::string &str, DeterminizeType *det_type);
 
 inline uint32 GetEncodeFlags(bool encode_labels, bool encode_weights) {
   return (encode_labels ? kEncodeLabels : 0) |
@@ -45,7 +44,7 @@ inline EpsNormalizeType GetEpsNormalizeType(bool eps_norm_output) {
   return eps_norm_output ? EPS_NORM_OUTPUT : EPS_NORM_INPUT;
 }
 
-bool GetMapType(const string &str, MapType *map_type);
+bool GetMapType(const std::string &str, MapType *map_type);
 
 inline ProjectType GetProjectType(bool project_output) {
   return project_output ? PROJECT_OUTPUT : PROJECT_INPUT;
@@ -59,11 +58,11 @@ inline uint32 GetPushFlags(bool push_weights, bool push_labels,
           (remove_common_affix ? kPushRemoveCommonAffix : 0));
 }
 
-bool GetQueueType(const string &str, QueueType *queue_type);
+bool GetQueueType(const std::string &str, QueueType *queue_type);
 
-bool GetRandArcSelection(const string &str, RandArcSelection *ras);
+bool GetRandArcSelection(const std::string &str, RandArcSelection *ras);
 
-bool GetReplaceLabelType(const string &str, bool epsilon_on_replace,
+bool GetReplaceLabelType(const std::string &str, bool epsilon_on_replace,
                          ReplaceLabelType *rlt);
 
 inline ReweightType GetReweightType(bool to_final) {
index e895649..9ba73ad 100644 (file)
@@ -35,8 +35,8 @@ class FstInfo {
   // minimal info is computed and can be requested.
   template <typename Arc>
   FstInfo(const Fst<Arc> &fst, bool test_properties,
-          const string &arc_filter_type = "any",
-          const string &info_type = "auto", bool verify = true)
+          const std::string &arc_filter_type = "any",
+          const std::string &info_type = "auto", bool verify = true)
       : fst_type_(fst.Type()),
         input_symbols_(fst.InputSymbols() ? fst.InputSymbols()->Name()
                                           : "none"),
@@ -165,17 +165,17 @@ class FstInfo {
 
   // Short info.
 
-  const string &FstType() const { return fst_type_; }
+  const std::string &FstType() const { return fst_type_; }
 
-  const string &ArcType() const { return arc_type_; }
+  const std::string &ArcType() const { return arc_type_; }
 
-  const string &InputSymbols() const { return input_symbols_; }
+  const std::string &InputSymbols() const { return input_symbols_; }
 
-  const string &OutputSymbols() const { return output_symbols_; }
+  const std::string &OutputSymbols() const { return output_symbols_; }
 
   bool LongInfo() const { return long_info_; }
 
-  const string &ArcFilterType() const { return arc_filter_type_; }
+  const std::string &ArcFilterType() const { return arc_filter_type_; }
 
   // Long info.
 
@@ -280,9 +280,9 @@ class FstInfo {
       FSTERROR() << "FstInfo: Method only available with long info signature";
   }
 
-  string fst_type_;
-  string input_symbols_;
-  string output_symbols_;
+  std::string fst_type_;
+  std::string input_symbols_;
+  std::string output_symbols_;
   int64 nstates_;
   size_t narcs_;
   int64 start_;
@@ -302,9 +302,9 @@ class FstInfo {
   bool input_lookahead_;
   bool output_lookahead_;
   uint64 properties_;
-  string arc_filter_type_;
+  std::string arc_filter_type_;
   bool long_info_;
-  string arc_type_;
+  std::string arc_type_;
 };
 
 void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe = false);
index 039d06d..dc6bdc1 100644 (file)
 namespace fst {
 namespace script {
 
-using InfoArgs = std::tuple<const FstClass &, bool, const string &,
-                            const string &, bool, bool>;
+using InfoArgs = std::tuple<const FstClass &, bool, const std::string &,
+                            const std::string &, bool, bool>;
 
 template <class Arc>
 void PrintFstInfo(InfoArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   const FstInfo fstinfo(fst, std::get<1>(*args), std::get<2>(*args),
                         std::get<3>(*args), std::get<4>(*args));
   PrintFstInfoImpl(fstinfo, std::get<5>(*args));
@@ -27,22 +27,22 @@ void PrintFstInfo(InfoArgs *args) {
 }
 
 void PrintFstInfo(const FstClass &f, bool test_properties,
-                  const string &arc_filter, const string &info_type, bool pipe,
-                  bool verify);
+                  const std::string &arc_filter, const std::string &info_type,
+                  bool pipe, bool verify);
 
-using GetInfoArgs = std::tuple<const FstClass &, bool, const string &,
-                               const string &, bool, FstInfo *>;
+using GetInfoArgs = std::tuple<const FstClass &, bool, const std::string &,
+                               const std::string &, bool, FstInfo *>;
 
 template <class Arc>
 void GetFstInfo(GetInfoArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   *(std::get<5>(*args)) = FstInfo(fst, std::get<1>(*args), std::get<2>(*args),
                                   std::get<3>(*args), std::get<4>(*args));
 }
 
 void GetFstInfo(const FstClass &fst, bool test_properties,
-                const string &arc_filter, const string &info_type, bool verify,
-                FstInfo *info);
+                const std::string &arc_filter, const std::string &info_type,
+                bool verify, FstInfo *info);
 
 }  // namespace script
 }  // namespace fst
index 229bd56..c2e311f 100644 (file)
@@ -18,8 +18,8 @@ using IntersectArgs = std::tuple<const FstClass &, const FstClass &,
 
 template <class Arc>
 void Intersect(IntersectArgs *args) {
-  const Fst<Arc> &ifst1 = *(std::get<0>(*args).GetFst<Arc>());
-  const Fst<Arc> &ifst2 = *(std::get<1>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst1 = *std::get<0>(*args).GetFst<Arc>();
+  const Fst<Arc> &ifst2 = *std::get<1>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<2>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<3>(*args);
   Intersect(ifst1, ifst2, ofst, opts);
index 94ea77f..7e82601 100644 (file)
@@ -20,8 +20,8 @@ using IsomorphicArgs = WithReturnValue<bool, IsomorphicInnerArgs>;
 
 template <class Arc>
 void Isomorphic(IsomorphicArgs *args) {
-  const Fst<Arc> &fst1 = *(std::get<0>(args->args).GetFst<Arc>());
-  const Fst<Arc> &fst2 = *(std::get<1>(args->args).GetFst<Arc>());
+  const Fst<Arc> &fst1 = *std::get<0>(args->args).GetFst<Arc>();
+  const Fst<Arc> &fst2 = *std::get<1>(args->args).GetFst<Arc>();
   args->retval = Isomorphic(fst1, fst2, std::get<2>(args->args));
 }
 
index 158d98a..38deed4 100644 (file)
@@ -60,7 +60,7 @@ using MapArgs = WithReturnValue<FstClass *, MapInnerArgs>;
 template <class Arc>
 void Map(MapArgs *args) {
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &ifst = *(std::get<0>(args->args).GetFst<Arc>());
+  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: {
@@ -95,7 +95,7 @@ void Map(MapArgs *args) {
       return;
     }
     case PLUS_MAPPER: {
-      const auto weight = *(std::get<4>(args->args).GetWeight<Weight>());
+      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);
       return;
@@ -123,7 +123,7 @@ void Map(MapArgs *args) {
       return;
     }
     case TIMES_MAPPER: {
-      const auto weight = *(std::get<4>(args->args).GetWeight<Weight>());
+      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);
       return;
index 773e8ef..15ea67c 100644 (file)
@@ -18,9 +18,9 @@ using MinimizeArgs = std::tuple<MutableFstClass *, MutableFstClass *, float,
 template <class Arc>
 void Minimize(MinimizeArgs *args) {
   MutableFst<Arc> *ofst1 = std::get<0>(*args)->GetMutableFst<Arc>();
-  MutableFst<Arc> *ofst2 = (std::get<1>(*args) ?
+  MutableFst<Arc> *ofst2 = std::get<1>(*args) ?
                             std::get<1>(*args)->GetMutableFst<Arc>() :
-                            nullptr);
+                            nullptr;
   Minimize(ofst1, ofst2, std::get<2>(*args), std::get<3>(*args));
 }
 
index 539c6d8..91ffdce 100644 (file)
@@ -30,8 +30,8 @@ class FstPrinter {
 
   FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
              const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             bool show_weight_one, const string &field_separator,
-             const string &missing_symbol = "")
+             bool show_weight_one, const std::string &field_separator,
+             const std::string &missing_symbol = "")
       : fst_(fst),
         isyms_(isyms),
         osyms_(osyms),
@@ -43,7 +43,7 @@ class FstPrinter {
         missing_symbol_(missing_symbol) {}
 
   // Prints FST to an output stream.
-  void Print(std::ostream *ostrm, const string &dest) {
+  void Print(std::ostream *ostrm, const std::string &dest) {
     ostrm_ = ostrm;
     dest_ = dest;
     const auto start = fst_.Start();
@@ -59,7 +59,7 @@ class FstPrinter {
  private:
   void PrintId(StateId id, const SymbolTable *syms, const char *name) const {
     if (syms) {
-      string symbol = syms->Find(id);
+      std::string symbol = syms->Find(id);
       if (symbol.empty()) {
         if (missing_symbol_.empty()) {
           FSTERROR() << "FstPrinter: Integer " << id
@@ -112,17 +112,17 @@ class FstPrinter {
   }
 
   const Fst<Arc> &fst_;
-  const SymbolTable *isyms_;  // ilabel symbol table.
-  const SymbolTable *osyms_;  // olabel symbol table.
-  const SymbolTable *ssyms_;  // slabel symbol table.
-  bool accep_;                // Print as acceptor when possible?
-  std::ostream *ostrm_;       // Text FST destination.
-  string dest_;               // Text FST destination name.
-  bool show_weight_one_;      // Print weights equal to Weight::One()?
-  string sep_;                // Separator character between fields.
-  string missing_symbol_;     // Symbol to print when lookup fails (default
-                              // "" means raise error).
-                              //
+  const SymbolTable *isyms_;    // ilabel symbol table.
+  const SymbolTable *osyms_;    // olabel symbol table.
+  const SymbolTable *ssyms_;    // slabel symbol table.
+  bool accep_;                  // Print as acceptor when possible?
+  std::ostream *ostrm_;         // Text FST destination.
+  std::string dest_;            // Text FST destination name.
+  bool show_weight_one_;        // Print weights equal to Weight::One()?
+  std::string sep_;             // Separator character between fields.
+  std::string missing_symbol_;  // Symbol to print when lookup fails (default
+                                // "" means raise error).
+
   FstPrinter(const FstPrinter &) = delete;
   FstPrinter &operator=(const FstPrinter &) = delete;
 };
index 687606b..05c57cc 100644 (file)
@@ -27,15 +27,15 @@ struct FstPrinterArgs {
   const bool accept;
   const bool show_weight_one;
   std::ostream *ostrm;
-  const string &dest;
-  const string &sep;  // NOLINT
-  const string &missing_symbol;
+  const std::string &dest;
+  const std::string &sep;  // NOLINT
+  const std::string &missing_symbol;
 
   FstPrinterArgs(const FstClass &fst, const SymbolTable *isyms,
                  const SymbolTable *osyms, const SymbolTable *ssyms,
                  bool accept, bool show_weight_one, std::ostream *ostrm,
-                 const string &dest, const string &sep,
-                 const string &missing_sym = "")
+                 const std::string &dest, const std::string &sep,
+                 const std::string &missing_sym = "")
       : fst(fst),
         isyms(isyms),
         osyms(osyms),
@@ -50,25 +50,25 @@ struct FstPrinterArgs {
 
 template <class Arc>
 void PrintFst(FstPrinterArgs *args) {
-  const Fst<Arc> &fst = *(args->fst.GetFst<Arc>());
+  const Fst<Arc> &fst = *args->fst.GetFst<Arc>();
   FstPrinter<Arc> fstprinter(fst, args->isyms, args->osyms, args->ssyms,
                              args->accept, args->show_weight_one, args->sep,
                              args->missing_symbol);
   fstprinter.Print(args->ostrm, args->dest);
 }
 
-void PrintFst(const FstClass &fst, std::ostream &ostrm, const string &dest,
+void PrintFst(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
               const SymbolTable *isyms, const SymbolTable *osyms,
               const SymbolTable *ssyms, bool accept, bool show_weight_one,
-              const string &missing_sym = "");
+              const std::string &missing_sym = "");
 
 // The same, but with more sensible defaults.
 template <class Arc>
-void PrintFst(const Fst<Arc> &fst, std::ostream &ostrm, const string &dest = "",
-              const SymbolTable *isyms = nullptr,
+void PrintFst(const Fst<Arc> &fst, std::ostream &ostrm,
+              const std::string &dest = "", const SymbolTable *isyms = nullptr,
               const SymbolTable *osyms = nullptr,
               const SymbolTable *ssyms = nullptr) {
-  const string sep = FLAGS_fst_field_separator.substr(0, 1);
+  const std::string sep = FLAGS_fst_field_separator.substr(0, 1);
   FstPrinter<Arc> fstprinter(fst, isyms, osyms, ssyms, true, true, sep);
   fstprinter.Print(&ostrm, dest);
 }
index ed10b54..e812fc6 100644 (file)
@@ -20,9 +20,9 @@ using PruneArgs1 = std::tuple<const FstClass &, MutableFstClass *,
 template <class Arc>
 void Prune(PruneArgs1 *args) {
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
-  const auto weight_threshold = *(std::get<2>(*args).GetWeight<Weight>());
+  const auto weight_threshold = *std::get<2>(*args).GetWeight<Weight>();
   Prune(ifst, ofst, weight_threshold, std::get<3>(*args), std::get<4>(*args));
 }
 
@@ -33,7 +33,7 @@ template <class Arc>
 void Prune(PruneArgs2 *args) {
   using Weight = typename Arc::Weight;
   MutableFst<Arc> *fst = std::get<0>(*args)->GetMutableFst<Arc>();
-  const auto weight_threshold = *(std::get<1>(*args).GetWeight<Weight>());
+  const auto weight_threshold = *std::get<1>(*args).GetWeight<Weight>();
   Prune(fst, weight_threshold, std::get<2>(*args), std::get<3>(*args));
 }
 
index 018cd8f..a8709b8 100644 (file)
@@ -25,7 +25,7 @@ using PushArgs2 = std::tuple<const FstClass &, MutableFstClass *, uint32,
 
 template <class Arc>
 void Push(PushArgs2 *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   switch (std::get<3>(*args)) {
     case REWEIGHT_TO_FINAL: {
index 945f8a0..225e1d5 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <climits>
 #include <ctime>
-
 #include <tuple>
 
 #include <fst/randequivalent.h>
@@ -24,8 +23,8 @@ using RandEquivalentArgs = WithReturnValue<bool, RandEquivalentInnerArgs>;
 
 template <class Arc>
 void RandEquivalent(RandEquivalentArgs *args) {
-  const Fst<Arc> &fst1 = *(std::get<0>(args->args).GetFst<Arc>());
-  const Fst<Arc> &fst2 = *(std::get<1>(args->args).GetFst<Arc>());
+  const Fst<Arc> &fst1 = *std::get<0>(args->args).GetFst<Arc>();
+  const Fst<Arc> &fst2 = *std::get<1>(args->args).GetFst<Arc>();
   const auto seed = std::get<4>(args->args);
   const auto &opts = std::get<5>(args->args);
   switch (opts.selector) {
index 5ce79d0..5f7a4a8 100644 (file)
@@ -5,7 +5,6 @@
 #define FST_SCRIPT_RANDGEN_H_
 
 #include <ctime>
-
 #include <tuple>
 
 #include <fst/randgen.h>
@@ -20,7 +19,7 @@ using RandGenArgs = std::tuple<const FstClass &, MutableFstClass *, time_t,
 
 template <class Arc>
 void RandGen(RandGenArgs *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   const time_t seed = std::get<2>(*args);
   const auto &opts = std::get<3>(*args);
index d66e7ad..ec53d60 100644 (file)
@@ -37,25 +37,25 @@ struct FstClassRegEntry {
 
 template <class Reader, class Creator, class Converter>
 class FstClassIORegister
-    : public GenericRegister<string,
+    : public GenericRegister<std::string,
                              FstClassRegEntry<Reader, Creator, Converter>,
                              FstClassIORegister<Reader, Creator, Converter>> {
  public:
-  Reader GetReader(const string &arc_type) const {
+  Reader GetReader(const std::string &arc_type) const {
     return this->GetEntry(arc_type).reader;
   }
 
-  Creator GetCreator(const string &arc_type) const {
+  Creator GetCreator(const std::string &arc_type) const {
     return this->GetEntry(arc_type).creator;
   }
 
-  Converter GetConverter(const string &arc_type) const {
+  Converter GetConverter(const std::string &arc_type) const {
     return this->GetEntry(arc_type).converter;
   }
 
  protected:
-  string ConvertKeyToSoFilename(const string &key) const final {
-    string legal_type(key);
+  std::string ConvertKeyToSoFilename(const std::string &key) const final {
+    std::string legal_type(key);
     ConvertToLegalCSymbol(&legal_type);
     return legal_type + "-arc.so";
   }
index 7444349..1671076 100644 (file)
 namespace fst {
 namespace script {
 
-using RelabelArgs1 = std::tuple<MutableFstClass *, const SymbolTable *,
-                                const SymbolTable *, const string &, bool,
-                                const SymbolTable *, const SymbolTable *,
-                                const string &, bool>;
+using RelabelArgs1 =
+    std::tuple<MutableFstClass *, const SymbolTable *, const SymbolTable *,
+               const std::string &, bool, const SymbolTable *,
+               const SymbolTable *, const std::string &, bool>;
 
 template <class Arc>
 void Relabel(RelabelArgs1 *args) {
@@ -49,11 +49,11 @@ void Relabel(RelabelArgs2 *args) {
   Relabel(ofst, typed_ipairs, typed_opairs);
 }
 
-void Relabel(MutableFstClass *ofst,
-             const SymbolTable *old_isymbols, const SymbolTable *new_isymbols,
-             const string &unknown_isymbol,  bool attach_new_isymbols,
+void Relabel(MutableFstClass *ofst, const SymbolTable *old_isymbols,
+             const SymbolTable *new_isymbols,
+             const std::string &unknown_isymbol, bool attach_new_isymbols,
              const SymbolTable *old_osymbols, const SymbolTable *new_osymbols,
-             const string &unknown_osymbol, bool attach_new_osymbols);
+             const std::string &unknown_osymbol, bool attach_new_osymbols);
 
 void Relabel(MutableFstClass *ofst, const std::vector<LabelPair> &ipairs,
              const std::vector<LabelPair> &opairs);
index badd96b..295e2a6 100644 (file)
@@ -16,7 +16,7 @@ using ReverseArgs = std::tuple<const FstClass &, MutableFstClass *, bool>;
 
 template <class Arc>
 void Reverse(ReverseArgs *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   Reverse(ifst, ofst, std::get<2>(*args));
 }
index 33c2853..07bbbf9 100644 (file)
 #include <string>
 #include <utility>
 
+#include <fst/log.h>
 #include <fst/generic-register.h>
 #include <fst/script/fst-class.h>
 
-#include <fst/log.h>
-
 namespace fst {
 namespace script {
 
@@ -97,29 +96,31 @@ enum RandArcSelection {
 
 // A generic register for operations with various kinds of signatures.
 // Needed since every function signature requires a new registration class.
-// The std::pair<string, string> is understood to be the operation name and arc
-// type; subclasses (or typedefs) need only provide the operation signature.
+// The std::pair<std::string, std::string> is understood to be the operation
+// name and arc type; subclasses (or typedefs) need only provide the operation
+// signature.
 
 template <class OperationSignature>
 class GenericOperationRegister
-    : public GenericRegister<std::pair<string, string>, OperationSignature,
+    : public GenericRegister<std::pair<std::string, std::string>,
+                             OperationSignature,
                              GenericOperationRegister<OperationSignature>> {
  public:
-  void RegisterOperation(const string &operation_name, const string &arc_type,
-                         OperationSignature op) {
+  void RegisterOperation(const std::string &operation_name,
+                         const std::string &arc_type, OperationSignature op) {
     this->SetEntry(std::make_pair(operation_name, arc_type), op);
   }
 
-  OperationSignature GetOperation(const string &operation_name,
-                                  const string &arc_type) {
+  OperationSignature GetOperation(const std::string &operation_name,
+                                  const std::string &arc_type) {
     return this->GetEntry(std::make_pair(operation_name, arc_type));
   }
 
  protected:
-  string ConvertKeyToSoFilename(
-      const std::pair<string, string> &key) const final {
+  std::string ConvertKeyToSoFilename(
+      const std::pair<std::string, std::string> &key) const final {
     // Uses the old-style FST for now.
-    string legal_type(key.second);  // The arc type.
+    std::string legal_type(key.second);  // The arc type.
     ConvertToLegalCSymbol(&legal_type);
     return legal_type + "-arc.so";
   }
@@ -155,7 +156,7 @@ struct Operation {
 // Template function to apply an operation by name.
 
 template <class OpReg>
-void Apply(const string &op_name, const string &arc_type,
+void Apply(const std::string &op_name, const std::string &arc_type,
            typename OpReg::ArgPack *args) {
   const auto op = OpReg::Register::GetRegister()->GetOperation(op_name,
                                                                arc_type);
@@ -173,7 +174,7 @@ namespace internal {
 // assuming that both m and n implement .ArcType(). The op_name argument is
 // used to construct the error message.
 template <class M, class N>
-bool ArcTypesMatch(const M &m, const N &n, const string &op_name) {
+bool ArcTypesMatch(const M &m, const N &n, const std::string &op_name) {
   if (m.ArcType() != n.ArcType()) {
     FSTERROR() << "Arguments with non-matching arc types passed to "
                << op_name << ":\t" << m.ArcType() << " and " << n.ArcType();
index a44a6c9..05f6db1 100644 (file)
@@ -143,7 +143,7 @@ template <class Arc>
 void ShortestDistance(ShortestDistanceArgs1 *args) {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   const auto &opts = std::get<2>(*args);
   std::vector<Weight> typed_distance;
   switch (opts.queue_type) {
@@ -194,7 +194,7 @@ using ShortestDistanceArgs2 =
 template <class Arc>
 void ShortestDistance(ShortestDistanceArgs2 *args) {
   using Weight = typename Arc::Weight;
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   std::vector<Weight> typed_distance;
   ShortestDistance(fst, &typed_distance, std::get<2>(*args),
                    std::get<3>(*args));
index 86bc88d..e1e6633 100644 (file)
@@ -101,7 +101,7 @@ using ShortestPathArgs = std::tuple<const FstClass &, MutableFstClass *,
 
 template <class Arc>
 void ShortestPath(ShortestPathArgs *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   const ShortestPathOptions &opts = std::get<2>(*args);
   internal::ShortestPath(ifst, ofst, opts);
index f6fddfe..6c7f8e4 100644 (file)
@@ -75,7 +75,7 @@ class StateIteratorClass {
 
 template <class Arc>
 void InitStateIteratorClass(InitStateIteratorClassArgs *args) {
-  const Fst<Arc> &fst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst = *std::get<0>(*args).GetFst<Arc>();
   std::get<1>(*args)->impl_.reset(new StateIteratorClassImpl<Arc>(fst));
 }
 
index 01df151..702ed5b 100644 (file)
@@ -16,7 +16,7 @@ using SynchronizeArgs = std::pair<const FstClass &, MutableFstClass *>;
 
 template <class Arc>
 void Synchronize(SynchronizeArgs *args) {
-  const Fst<Arc> &ifst = *(std::get<0>(*args).GetFst<Arc>());
+  const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   Synchronize(ifst, ofst);
 }
index 464bf88..c964072 100644 (file)
 namespace fst {
 namespace script {
 
-bool ReadPotentials(const string &weight_type, const string &filename,
+bool ReadPotentials(const std::string &weight_type, const std::string &filename,
                     std::vector<WeightClass> *potentials);
 
-bool WritePotentials(const string &filename,
+bool WritePotentials(const std::string &filename,
                      const std::vector<WeightClass> &potentials);
 
 }  // namespace script
index 9493e2b..d779250 100644 (file)
@@ -17,7 +17,7 @@ using UnionArgs = std::pair<MutableFstClass *, const FstClass &>;
 template <class Arc>
 void Union(UnionArgs *args) {
   MutableFst<Arc> *fst1 = std::get<0>(*args)->GetMutableFst<Arc>();
-  const Fst<Arc> &fst2 = *(std::get<1>(*args).GetFst<Arc>());
+  const Fst<Arc> &fst2 = *std::get<1>(*args).GetFst<Arc>();
   Union(fst1, fst2);
 }
 
index 52f5864..53f4852 100644 (file)
@@ -15,7 +15,7 @@ using VerifyArgs = WithReturnValue<bool, const FstClass &>;
 
 template <class Arc>
 void Verify(VerifyArgs *args) {
-  const Fst<Arc> &fst = *(args->args.GetFst<Arc>());
+  const Fst<Arc> &fst = *args->args.GetFst<Arc>();
   args->retval = Verify(fst);
 }
 
index 5f71ed8..947cbe8 100644 (file)
@@ -23,8 +23,8 @@ class WeightImplBase {
  public:
   virtual WeightImplBase *Copy() const = 0;
   virtual void Print(std::ostream *o) const = 0;
-  virtual const string &Type() const = 0;
-  virtual string ToString() const = 0;
+  virtual const std::string &Type() const = 0;
+  virtual std::string ToString() const = 0;
   virtual bool Member() const = 0;
   virtual bool operator==(const WeightImplBase &other) const = 0;
   virtual bool operator!=(const WeightImplBase &other) const = 0;
@@ -44,12 +44,12 @@ class WeightClassImpl : public WeightImplBase {
     return new WeightClassImpl<W>(weight_);
   }
 
-  const string &Type() const final { return W::Type(); }
+  const std::string &Type() const final { return W::Type(); }
 
   void Print(std::ostream *ostrm) const final { *ostrm << weight_; }
 
-  string ToString() const final {
-    string str;
+  std::string ToString() const final {
+    std::string str;
     WeightToStr(weight_, &str);
     return str;
   }
@@ -107,7 +107,7 @@ class WeightClass {
   explicit WeightClass(const WeightClassImpl<W> &impl)
       : impl_(new WeightClassImpl<W>(impl)) {}
 
-  WeightClass(const string &weight_type, const string &weight_str);
+  WeightClass(const std::string &weight_type, const std::string &weight_str);
 
   WeightClass(const WeightClass &other)
       : impl_(other.impl_ ? other.impl_->Copy() : nullptr) {}
@@ -119,15 +119,15 @@ class WeightClass {
 
   static constexpr const char *__ZERO__ = "__ZERO__";  // NOLINT
 
-  static WeightClass Zero(const string &weight_type);
+  static WeightClass Zero(const std::string &weight_type);
 
   static constexpr const char *__ONE__ = "__ONE__";  // NOLINT
 
-  static WeightClass One(const string &weight_type);
+  static WeightClass One(const std::string &weight_type);
 
   static constexpr const char *__NOWEIGHT__ = "__NOWEIGHT__";  // NOLINT
 
-  static WeightClass NoWeight(const string &weight_type);
+  static WeightClass NoWeight(const std::string &weight_type);
 
   template <class W>
   const W *GetWeight() const {
@@ -139,17 +139,18 @@ class WeightClass {
     }
   }
 
-  string ToString() const { return (impl_) ? impl_->ToString() : "none"; }
+  std::string ToString() const { return (impl_) ? impl_->ToString() : "none"; }
 
-  const string &Type() const {
+  const std::string &Type() const {
     if (impl_) return impl_->Type();
-    static const string *const no_type = new string("none");
+    static const std::string *const no_type = new std::string("none");
     return *no_type;
   }
 
   bool Member() const { return impl_ && impl_->Member(); }
 
-  bool WeightTypesMatch(const WeightClass &other, const string &op_name) const;
+  bool WeightTypesMatch(const WeightClass &other,
+                        const std::string &op_name) const;
 
   friend bool operator==(const WeightClass &lhs, const WeightClass &rhs);
 
@@ -187,27 +188,29 @@ std::ostream &operator<<(std::ostream &o, const WeightClass &c);
 
 // Registration for generic weight types.
 
-using StrToWeightImplBaseT = WeightImplBase *(*)(const string &str,
-                                                 const string &src,
+using StrToWeightImplBaseT = WeightImplBase *(*)(const std::string &str,
+                                                 const std::string &src,
                                                  size_t nline);
 
 template <class W>
-WeightImplBase *StrToWeightImplBase(const string &str, const string &src,
-                                    size_t nline) {
-  if (str == WeightClass::__ZERO__)
+WeightImplBase *StrToWeightImplBase(const std::string &str,
+                                    const std::string &src, size_t nline) {
+  if (str == WeightClass::__ZERO__) {
     return new WeightClassImpl<W>(W::Zero());
-  else if (str == WeightClass::__ONE__)
+  } else if (str == WeightClass::__ONE__) {
     return new WeightClassImpl<W>(W::One());
-  else if (str == WeightClass::__NOWEIGHT__)
+  } else if (str == WeightClass::__NOWEIGHT__) {
     return new WeightClassImpl<W>(W::NoWeight());
+  }
   return new WeightClassImpl<W>(StrToWeight<W>(str, src, nline));
 }
 
-class WeightClassRegister : public GenericRegister<string, StrToWeightImplBaseT,
-                                                   WeightClassRegister> {
+class WeightClassRegister
+    : public GenericRegister<std::string, StrToWeightImplBaseT,
+                             WeightClassRegister> {
  protected:
-  string ConvertKeyToSoFilename(const string &key) const final {
-    string legal_type(key);
+  std::string ConvertKeyToSoFilename(const std::string &key) const final {
+    std::string legal_type(key);
     ConvertToLegalCSymbol(&legal_type);
     return legal_type + ".so";
   }
index 202fa52..af76dfb 100644 (file)
@@ -8,9 +8,8 @@
 #ifndef FST_SET_WEIGHT_H_
 #define FST_SET_WEIGHT_H_
 
-#include <cstdlib>
-
 #include <algorithm>
+#include <cstdlib>
 #include <list>
 #include <string>
 #include <vector>
@@ -102,15 +101,15 @@ class SetWeight {
     return *no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type = new string(
-        S == SET_UNION_INTERSECT
-        ? "union_intersect_set"
-        : (S == SET_INTERSECT_UNION
-           ? "intersect_union_set"
-           : (S == SET_INTERSECT_UNION_RESTRICT
-              ? "restricted_set_intersect_union"
-              : "boolean_set")));
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string(S == SET_UNION_INTERSECT
+                            ? "union_intersect_set"
+                            : (S == SET_INTERSECT_UNION
+                                   ? "intersect_union_set"
+                                   : (S == SET_INTERSECT_UNION_RESTRICT
+                                          ? "restricted_set_intersect_union"
+                                          : "boolean_set")));
     return *type;
   }
 
@@ -339,7 +338,7 @@ inline std::ostream &operator<<(std::ostream &strm,
 template <typename Label, SetType S>
 inline std::istream &operator>>(std::istream &strm,
                                 SetWeight<Label, S> &weight) {
-  string str;
+  std::string str;
   strm >> str;
   using Weight = SetWeight<Label, S>;
   if (str == "EmptySet") {
index 7bd0471..5311dae 100644 (file)
@@ -359,9 +359,9 @@ void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
   }
   ofst->SetStart(ofst->AddState());
   const auto final_state = ofst->AddState();
-  ofst->SetFinal(final_state, Weight::One());
+  ofst->SetFinal(final_state);
   while (pairs.size() <= final_state) {
-    pairs.push_back(std::make_pair(kNoStateId, Weight::Zero()));
+    pairs.emplace_back(kNoStateId, Weight::Zero());
   }
   pairs[final_state] = std::make_pair(ifst.Start(), Weight::One());
   std::vector<StateId> heap;
@@ -387,9 +387,7 @@ void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
     }
     while (r.size() <= p.first + 1) r.push_back(0);
     ++r[p.first + 1];
-    if (p.first == kNoStateId) {
-      ofst->AddArc(ofst->Start(), Arc(0, 0, Weight::One(), state));
-    }
+    if (p.first == kNoStateId) ofst->AddArc(ofst->Start(), Arc(0, 0, state));
     if ((p.first == kNoStateId) && (r[p.first + 1] == nshortest)) break;
     if (r[p.first + 1] > nshortest) continue;
     if (p.first == kNoStateId) continue;
@@ -399,7 +397,7 @@ void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
       Arc arc(rarc.ilabel, rarc.olabel, rarc.weight.Reverse(), rarc.nextstate);
       const auto weight = Times(p.second, arc.weight);
       const auto next = ofst->AddState();
-      pairs.push_back(std::make_pair(arc.nextstate, weight));
+      pairs.emplace_back(arc.nextstate, weight);
       arc.nextstate = state;
       ofst->AddArc(next, std::move(arc));
       heap.push_back(next);
@@ -409,7 +407,7 @@ void NShortestPath(const Fst<RevArc> &ifst, MutableFst<Arc> *ofst,
     if (final_weight != Weight::Zero()) {
       const auto weight = Times(p.second, final_weight);
       const auto next = ofst->AddState();
-      pairs.push_back(std::make_pair(kNoStateId, weight));
+      pairs.emplace_back(kNoStateId, weight);
       ofst->AddArc(next, Arc(0, 0, final_weight, state));
       heap.push_back(next);
       std::push_heap(heap.begin(), heap.end(), compare);
index 41339bc..98f6f21 100644 (file)
@@ -51,9 +51,9 @@ class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type =
-        new string("signed_log_" + X1::Type() + "_" + X2::Type());
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string("signed_log_" + X1::Type() + "_" + X2::Type());
     return *type;
   }
 
@@ -105,7 +105,7 @@ inline SignedLogWeightTpl<T> Plus(const SignedLogWeightTpl<T> &w1,
     return w1;
   } else if (f1 == f2) {
     if (equal) {
-      return SignedLogWeightTpl<T>(X1(w1.Value1()), X2(f2 - log(2.0F)));
+      return SignedLogWeightTpl<T>(X1(w1.Value1()), X2(f2 - M_LN2));
     } else {
       return SignedLogWeightTpl<T>::Zero();
     }
index b7f2098..3db3214 100644 (file)
@@ -32,48 +32,49 @@ namespace fst {
 template <class W, class K = int>
 class SparsePowerWeight : public SparseTupleWeight<W, K> {
  public:
+  using Base = SparseTupleWeight<W, K>;
   using ReverseWeight = SparsePowerWeight<typename W::ReverseWeight, K>;
 
   SparsePowerWeight() {}
 
-  explicit SparsePowerWeight(const SparseTupleWeight<W, K> &weight)
-      : SparseTupleWeight<W, K>(weight) {}
+  explicit SparsePowerWeight(const Base &weight)
+      : Base(weight) {}
 
   template <class Iterator>
   SparsePowerWeight(Iterator begin, Iterator end)
-      : SparseTupleWeight<W, K>(begin, end) {}
+      : Base(begin, end) {}
 
   // Initialize component `key` to `weight`, with `default_weight` for all
   // other components.
   SparsePowerWeight(const K &key, const W &weight,
                     const W &default_weight = W::Zero())
-      : SparseTupleWeight<W, K>(key, weight, default_weight) {}
+      : Base(key, weight, default_weight) {}
 
   static const SparsePowerWeight &Zero() {
-    static const SparsePowerWeight zero(SparseTupleWeight<W, K>::Zero());
+    static const SparsePowerWeight zero(Base::Zero());
     return zero;
   }
 
   static const SparsePowerWeight &One() {
-    static const SparsePowerWeight one(SparseTupleWeight<W, K>::One());
+    static const SparsePowerWeight one(Base::One());
     return one;
   }
 
   static const SparsePowerWeight &NoWeight() {
     static const SparsePowerWeight no_weight(
-        SparseTupleWeight<W, K>::NoWeight());
+        Base::NoWeight());
     return no_weight;
   }
 
   // Overide this: Overwrite the Type method to reflect the key type if using
   // a non-default key type.
-  static const string &Type() {
-    static const string *const type = [] {
-      string type = W::Type() + "_^n";
+  static const std::string &Type() {
+    static const std::string *const type = [] {
+      std::string type = W::Type() + "_^n";
       if (sizeof(K) != sizeof(uint32)) {
         type += "_" + std::to_string(CHAR_BIT * sizeof(K));
       }
-      return new string(type);
+      return new std::string(type);
     }();
     return *type;
   }
@@ -84,11 +85,11 @@ class SparsePowerWeight : public SparseTupleWeight<W, K> {
   }
 
   SparsePowerWeight Quantize(float delta = kDelta) const {
-    return SparsePowerWeight(SparseTupleWeight<W, K>::Quantize(delta));
+    return SparsePowerWeight(Base::Quantize(delta));
   }
 
   ReverseWeight Reverse() const {
-    return ReverseWeight(SparseTupleWeight<W, K>::Reverse());
+    return ReverseWeight(Base::Reverse());
   }
 };
 
index 8bd9e36..662e7d5 100644 (file)
@@ -7,7 +7,6 @@
 #define FST_STRING_WEIGHT_H_
 
 #include <cstdlib>
-
 #include <list>
 #include <string>
 #include <vector>
@@ -76,8 +75,8 @@ class StringWeight {
     return *no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type = new string(
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
         S == STRING_LEFT
             ? "left_string"
             : (S == STRING_RIGHT ? "right_string" : "restricted_string"));
@@ -311,7 +310,7 @@ inline std::ostream &operator<<(std::ostream &strm,
 template <typename Label, StringType S>
 inline std::istream &operator>>(std::istream &strm,
                                 StringWeight<Label, S> &weight) {
-  string str;
+  std::string str;
   strm >> str;
   using Weight = StringWeight<Label, S>;
   if (str == "Infinity") {
@@ -468,7 +467,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 string semiring";
+               << "for the left std::string semiring";
     return StringWeight<Label, STRING_LEFT>::NoWeight();
   }
   return DivideLeft(w1, w2);
@@ -481,7 +480,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 string semiring";
+               << "for the right std::string semiring";
     return StringWeight<Label, STRING_RIGHT>::NoWeight();
   }
   return DivideRight(w1, w2);
@@ -565,7 +564,7 @@ struct GallicWeight
 
   GallicWeight(SW w1, W w2) : ProductWeight<SW, W>(w1, w2) {}
 
-  explicit GallicWeight(const string &s, int *nread = nullptr)
+  explicit GallicWeight(const std::string &s, int *nread = nullptr)
       : ProductWeight<SW, W>(s, nread) {}
 
   explicit GallicWeight(const ProductWeight<SW, W> &w)
@@ -586,8 +585,8 @@ struct GallicWeight
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type = new string(
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
         G == GALLIC_LEFT
             ? "left_gallic"
             : (G == GALLIC_RIGHT
@@ -721,7 +720,7 @@ struct GallicWeight<Label, W, GALLIC>
 
   GallicWeight(SW w1, W w2) : UW(GW(w1, w2)) {}
 
-  explicit GallicWeight(const string &str, int *nread = nullptr)
+  explicit GallicWeight(const std::string &str, int *nread = nullptr)
       : UW(str, nread) {}
 
   static const GallicWeight<Label, W, GALLIC> &Zero() {
@@ -739,8 +738,8 @@ struct GallicWeight<Label, W, GALLIC>
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type = new string("gallic");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("gallic");
     return *type;
   }
 
index 07ebfdd..c07eb69 100644 (file)
@@ -17,6 +17,8 @@
 #include <fst/compact-fst.h>
 #include <fst/icu.h>
 #include <fst/mutable-fst.h>
+#include <fst/properties.h>
+#include <fst/symbol-table.h>
 #include <fst/util.h>
 
 
@@ -35,8 +37,8 @@ bool ConvertSymbolToLabel(const char *str, const SymbolTable *syms,
   int64 n;
   if (syms) {
     n = syms->Find(str);
-    if ((n == -1) && (unknown_label != kNoLabel)) n = unknown_label;
-    if (n == -1 || (!allow_negative && n < 0)) {
+    if ((n == kNoSymbol) && (unknown_label != kNoLabel)) n = unknown_label;
+    if (n == kNoSymbol || (!allow_negative && n < 0)) {
       LOG(ERROR) << "ConvertSymbolToLabel: Symbol \"" << str
                  << "\" is not mapped to any integer label, symbol table = "
                  << syms->Name();
@@ -56,7 +58,7 @@ bool ConvertSymbolToLabel(const char *str, const SymbolTable *syms,
 }
 
 template <class Label>
-bool ConvertStringToLabels(const string &str, StringTokenType token_type,
+bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
                            const SymbolTable *syms, Label unknown_label,
                            bool allow_negative, std::vector<Label> *labels) {
   labels->clear();
@@ -70,7 +72,7 @@ bool ConvertStringToLabels(const string &str, StringTokenType token_type,
     str.copy(c_str.get(), str.size());
     c_str[str.size()] = 0;
     std::vector<char *> vec;
-    const string separator = "\n" + FLAGS_fst_field_separator;
+    const std::string separator = "\n" + FLAGS_fst_field_separator;
     SplitString(c_str.get(), separator.c_str(), &vec, true);
     for (const char *c : vec) {
       Label label;
@@ -87,88 +89,47 @@ bool ConvertStringToLabels(const string &str, StringTokenType token_type,
 // The sep string is used as a separator between symbols, unless it is nullptr,
 // in which case the last character of FLAGS_fst_field_separator is used.
 template <class Label>
-bool LabelsToSymbolString(const std::vector<Label> &labels, string *str,
+bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
                           const SymbolTable &syms,
-                          const string *sep = nullptr) {
+                          const std::string *sep = nullptr) {
   std::stringstream ostrm;
-  string delim = "";
+  std::string delim = "";
   for (auto label : labels) {
     ostrm << delim;
-    const string &symbol = syms.Find(label);
+    const std::string &symbol = syms.Find(label);
     if (symbol.empty()) {
-      LOG(ERROR) << "LabelToSymbolString: Label " << label
+      LOG(ERROR) << "LabelsToSymbolString: Label " << label
                  << " is not mapped onto any textual symbol in symbol table "
                  << syms.Name();
       return false;
     }
     ostrm << symbol;
-    delim = sep != nullptr ? *sep : string(1, FLAGS_fst_field_separator.back());
+    delim = sep != nullptr ? *sep
+                           : std::string(1, FLAGS_fst_field_separator.back());
   }
   *str = ostrm.str();
   return !!ostrm;
 }
 
-}  // namespace internal
-
-// TODO(kbg): Move this just before StringPrinter.
-// Converts an FST to a vector of output labels. To get input labels, use
-// Project or Invert. Returns true on success. Use only with string FSTs; may
-// loop for non-string FSTs.
-template <class Arc>
-bool StringFstToOutputLabels(const Fst<Arc> &fst,
-                             std::vector<typename Arc::Label> *labels) {
-  labels->clear();
-  auto s = fst.Start();
-  if (s == kNoStateId) {
-    LOG(ERROR) << "StringFstToOutputLabels: Invalid start state";
-    return false;
-  }
-  while (fst.Final(s) == Arc::Weight::Zero()) {
-    ArcIterator<Fst<Arc>> aiter(fst, s);
-    if (aiter.Done()) {
-      LOG(ERROR) << "StringFstToOutputLabels: Does not reach final state";
-      return false;
-    }
-    const auto &arc = aiter.Value();
-    labels->push_back(arc.olabel);
-    s = arc.nextstate;
-    aiter.Next();
-    if (!aiter.Done()) {
-      LOG(ERROR) << "StringFstToOutputLabels: State has multiple outgoing arcs";
-      return false;
-    }
-  }
-  if (fst.NumArcs(s) != 0) {
-    LOG(ERROR) << "FstToOutputLabels: Final state has outgoing arc(s)";
-    return false;
-  }
-  return true;
-}
-
-// TODO(kbg): Move this just before StringPrinter.
-// Converts a list of symbols to a string. Returns true on success. If the token
-// type is SYMBOL and sep is provided, it is used to separate textual symbols.
-// If the token type is SYMBOL and it is not provided, the last character of
-// FLAGS_fst_field_separator is used.
+// The sep string is used as a separator between symbols, unless it is nullptr,
+// in which case the last character of FLAGS_fst_field_separator is used.
 template <class Label>
-bool LabelsToString(const std::vector<Label> &labels, string *str,
-                    StringTokenType ttype = BYTE,
-                    const SymbolTable *syms = nullptr,
-                    const string *sep = nullptr) {
-  switch (ttype) {
-    case StringTokenType::BYTE: {
-      return LabelsToByteString(labels, str);
-    }
-    case StringTokenType::UTF8: {
-      return LabelsToUTF8String(labels, str);
-    }
-    case StringTokenType::SYMBOL: {
-      return internal::LabelsToSymbolString(labels, str, *syms, sep);
-    }
+bool LabelsToNumericString(const std::vector<Label> &labels, std::string *str,
+                           const std::string *sep = nullptr) {
+  std::stringstream ostrm;
+  std::string delim = "";
+  for (auto label : labels) {
+    ostrm << delim;
+    ostrm << label;
+    delim = sep != nullptr ? *sep
+                           : std::string(1, FLAGS_fst_field_separator.back());
   }
-  return false;
+  *str = ostrm.str();
+  return !!ostrm;
 }
 
+}  // namespace internal
+
 // Functor for compiling a string in an FST.
 template <class Arc>
 class StringCompiler {
@@ -188,7 +149,7 @@ class StringCompiler {
 
   // Compiles string into an FST.
   template <class FST>
-  bool operator()(const string &str, FST *fst) const {
+  bool operator()(const std::string &str, FST *fst) const {
     std::vector<Label> labels;
     if (!internal::ConvertStringToLabels(str, token_type_, syms_,
                                          unknown_label_, allow_negative_,
@@ -200,7 +161,7 @@ class StringCompiler {
   }
 
   template <class FST>
-  bool operator()(const string &str, FST *fst, Weight weight) const {
+  bool operator()(const std::string &str, FST *fst, Weight weight) const {
     std::vector<Label> labels;
     if (!internal::ConvertStringToLabels(str, token_type_, syms_,
                                          unknown_label_, allow_negative_,
@@ -215,12 +176,15 @@ class StringCompiler {
   void Compile(const std::vector<Label> &labels, MutableFst<Arc> *fst,
                Weight weight = Weight::One()) const {
     fst->DeleteStates();
-    while (fst->NumStates() <= labels.size()) fst->AddState();
-    for (StateId i = 0; i < labels.size(); ++i) {
-      fst->AddArc(i, Arc(labels[i], labels[i], Weight::One(), i + 1));
+    auto state = fst->AddState();
+    fst->SetStart(state);
+    fst->AddStates(labels.size());
+    for (auto label : labels) {
+      fst->AddArc(state, Arc(label, label, state + 1));
+      ++state;
     }
-    fst->SetStart(0);
-    fst->SetFinal(labels.size(), std::move(weight));
+    fst->SetFinal(state, std::move(weight));
+    fst->SetProperties(kCompiledStringProperties, kCompiledStringProperties);
   }
 
   template <class Unsigned>
@@ -232,7 +196,7 @@ class StringCompiler {
   template <class Unsigned>
   void Compile(const std::vector<Label> &labels,
                CompactWeightedStringFst<Arc, Unsigned> *fst,
-               const Weight &weight = Weight::One()) const {
+               Weight weight = Weight::One()) const {
     std::vector<std::pair<Label, Weight>> compacts;
     compacts.reserve(labels.size() + 1);
     for (StateId i = 0; i < static_cast<StateId>(labels.size()) - 1; ++i) {
@@ -253,6 +217,65 @@ class StringCompiler {
 
 // Helpers for StringPrinter.
 
+// Converts an FST to a vector of output labels. To get input labels, use
+// Project or Invert. Returns true on success. Use only with string FSTs; may
+// loop for non-string FSTs.
+template <class Arc>
+bool StringFstToOutputLabels(const Fst<Arc> &fst,
+                             std::vector<typename Arc::Label> *labels) {
+  labels->clear();
+  auto s = fst.Start();
+  if (s == kNoStateId) {
+    LOG(ERROR) << "StringFstToOutputLabels: Invalid start state";
+    return false;
+  }
+  while (fst.Final(s) == Arc::Weight::Zero()) {
+    ArcIterator<Fst<Arc>> aiter(fst, s);
+    if (aiter.Done()) {
+      LOG(ERROR) << "StringFstToOutputLabels: Does not reach final state";
+      return false;
+    }
+    const auto &arc = aiter.Value();
+    labels->push_back(arc.olabel);
+    s = arc.nextstate;
+    aiter.Next();
+    if (!aiter.Done()) {
+      LOG(ERROR) << "StringFstToOutputLabels: State has multiple outgoing arcs";
+      return false;
+    }
+  }
+  if (fst.NumArcs(s) != 0) {
+    LOG(ERROR) << "StringFstToOutputLabels: Final state has outgoing arc(s)";
+    return false;
+  }
+  return true;
+}
+
+// Converts a list of symbols to a string. Returns true on success. If the token
+// type is SYMBOL and sep is provided, it is used to separate textual symbols.
+// If the token type is SYMBOL and it is not provided, the last character of
+// FLAGS_fst_field_separator is used.
+template <class Label>
+bool LabelsToString(const std::vector<Label> &labels, std::string *str,
+                    StringTokenType ttype = BYTE,
+                    const SymbolTable *syms = nullptr,
+                    const std::string *sep = nullptr) {
+  switch (ttype) {
+    case StringTokenType::BYTE: {
+      return LabelsToByteString(labels, str);
+    }
+    case StringTokenType::UTF8: {
+      return LabelsToUTF8String(labels, str);
+    }
+    case StringTokenType::SYMBOL: {
+      return syms ?
+          internal::LabelsToSymbolString(labels, str, *syms, sep) :
+          internal::LabelsToNumericString(labels, str, sep);
+    }
+  }
+  return false;
+}
+
 // Functor for printing a string FST as a string.
 template <class Arc>
 class StringPrinter {
@@ -266,8 +289,8 @@ class StringPrinter {
   // Converts the FST into a string. With SYMBOL token type, sep is used as a
   // separator between symbols, unless it is nullptr, in which case the last
   // character of FLAGS_fst_field_separator is used. Returns true on success.
-  bool operator()(const Fst<Arc> &fst, string *str,
-                  const string *sep = nullptr) const {
+  bool operator()(const Fst<Arc> &fst, std::string *str,
+                  const std::string *sep = nullptr) const {
     std::vector<Label> labels;
     return (StringFstToOutputLabels(fst, &labels) &&
             LabelsToString(labels, str, token_type_, syms_, sep));
index 38f9d81..740cd75 100644 (file)
@@ -42,35 +42,36 @@ SymbolTable *PruneSymbolTable(const Fst<Arc> &fst, const SymbolTable &syms,
 SymbolTable *CompactSymbolTable(const SymbolTable &syms);
 
 // Merges two SymbolTables, all symbols from left will be merged into right
-// with the same ids.  Symbols in right that have conflicting ids with those
+// with the same IDs. Symbols in right that have conflicting IDs with those
 // in left will be assigned to value assigned from the left SymbolTable.
 // The returned symbol table will never modify symbol assignments from the left
-// side, but may do so on the right.  If right_relabel_output is non-NULL, it
+// side, but may do so on the right. If right_relabel_output is non-null, it
 // will be assigned true if the symbols from the right table needed to be
 // reassigned.
-// A potential use case is to Compose two Fst's that have different symbol
-// tables.  You can reconcile them in the following way:
+//
+// A potential use case is to compose two FSTs that have different symbol
+// tables. You can reconcile them in the following way:
+//
 //   Fst<Arc> a, b;
 //   bool relabel;
 //   std::unique_ptr<SymbolTable> bnew(MergeSymbolTable(a.OutputSymbols(),
 //                                     b.InputSymbols(), &relabel);
-//   if (relabel) {
-//     Relabel(b, bnew.get(), nullptr);
-//   }
+//   if (relabel) Relabel(b, bnew.get(), nullptr);
 //   b.SetInputSymbols(bnew);
 SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
                               bool *right_relabel_output = nullptr);
 
 // Read the symbol table from any Fst::Read()able file, without loading the
-// corresponding Fst.  Returns nullptr if the Fst does not contain a symbol
+// corresponding FST. Returns nullptr if the FST does not contain a symbol
 // table or the symbol table cannot be read.
-SymbolTable *FstReadSymbols(const string &filename, bool input);
+SymbolTable *FstReadSymbols(const std::string &filename, bool input);
 
 // Adds a contiguous range of symbols to a symbol table using a simple prefix
 // for the string, returning false if the inserted symbol string clashes with
 // any currently present.
-bool AddAuxiliarySymbols(const string &prefix, int64 start_label,
+bool AddAuxiliarySymbols(const std::string &prefix, int64 start_label,
                          int64 nlabels, SymbolTable *syms);
 
 }  // namespace fst
+
 #endif  // FST_SYMBOL_TABLE_OPS_H_
index 2884bc3..f766813 100644 (file)
@@ -12,6 +12,7 @@
 #include <memory>
 #include <sstream>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
 #include <fst/log.h>
 #include <fstream>
 #include <map>
+#include <functional>
+
+#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_compat_symbols);
 
@@ -35,18 +51,18 @@ struct SymbolTableReadOptions {
 
   SymbolTableReadOptions(
       std::vector<std::pair<int64, int64>> string_hash_ranges,
-      const string &source)
+      const std::string &source)
       : string_hash_ranges(std::move(string_hash_ranges)), source(source) {}
 
   std::vector<std::pair<int64, int64>> string_hash_ranges;
-  string source;
+  std::string source;
 };
 
 struct SymbolTableTextOptions {
   explicit SymbolTableTextOptions(bool allow_negative_labels = false);
 
   bool allow_negative_labels;
-  string fst_field_separator;
+  std::string fst_field_separator;
 };
 
 namespace internal {
@@ -57,17 +73,25 @@ extern const int kLineLen;
 // 75% occupancy.
 class DenseSymbolMap {
  public:
+  // Argument type for symbol lookups and inserts.
+
+#ifdef OPENFST_HAVE_STD_STRING_VIEW
+  using KeyType = std::string_view;
+#else
+  using KeyType = const std::string &;
+#endif  // OPENFST_HAVE_STD_STRING_VIEW
+
   DenseSymbolMap();
 
   DenseSymbolMap(const DenseSymbolMap &x);
 
-  std::pair<int64, bool> InsertOrFind(const string &key);
+  std::pair<int64, bool> InsertOrFind(KeyType key);
 
-  int64 Find(const string &key) const;
+  int64 Find(KeyType key) const;
 
   size_t Size() const { return symbols_.size(); }
 
-  const string &GetSymbol(size_t idx) const { return symbols_[idx]; }
+  const std::string &GetSymbol(size_t idx) const { return symbols_[idx]; }
 
   void RemoveSymbol(size_t idx);
 
@@ -75,16 +99,20 @@ class DenseSymbolMap {
   // num_buckets must be power of 2.
   void Rehash(size_t num_buckets);
 
+  std::hash<typename std::remove_const<
+      typename std::remove_reference<KeyType>::type>::type>
+      str_hash_;
   int64 empty_;
-  std::vector<string> symbols_;
-  std::hash<string> str_hash_;
+  std::vector<std::string> symbols_;
   std::vector<int64> buckets_;
   uint64 hash_mask_;
 };
 
 class SymbolTableImpl {
  public:
-  explicit SymbolTableImpl(const string &name)
+  using SymbolType = DenseSymbolMap::KeyType;
+
+  explicit SymbolTableImpl(const std::string &name)
       : name_(name),
         available_key_(0),
         dense_key_limit_(0),
@@ -99,9 +127,9 @@ class SymbolTableImpl {
         key_map_(impl.key_map_),
         check_sum_finalized_(false) {}
 
-  int64 AddSymbol(const string &symbol, int64 key);
+  int64 AddSymbol(SymbolType symbol, int64 key);
 
-  int64 AddSymbol(const string &symbol) {
+  int64 AddSymbol(SymbolType symbol) {
     return AddSymbol(symbol, available_key_);
   }
 
@@ -111,7 +139,7 @@ class SymbolTableImpl {
   void RemoveSymbol(int64 key);
 
   static SymbolTableImpl *ReadText(
-      std::istream &strm, const string &name,
+      std::istream &strm, const std::string &name,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions());
 
   static SymbolTableImpl* Read(std::istream &strm,
@@ -121,7 +149,7 @@ class SymbolTableImpl {
 
   // Return the string associated with the key. If the key is out of
   // range (<0, >max), return an empty string.
-  string Find(int64 key) const {
+  std::string Find(int64 key) const {
     int64 idx = key;
     if (key < 0 || key >= dense_key_limit_) {
       const auto it = key_map_.find(key);
@@ -134,7 +162,7 @@ class SymbolTableImpl {
 
   // Returns the key associated with the symbol; if the symbol
   // does not exists, returns kNoSymbol.
-  int64 Find(const string &symbol) const {
+  int64 Find(SymbolType symbol) const {
     int64 idx = symbols_.Find(symbol);
     if (idx == kNoSymbol || idx < dense_key_limit_) return idx;
     return idx_key_[idx - dense_key_limit_];
@@ -142,7 +170,7 @@ class SymbolTableImpl {
 
   bool Member(int64 key) const { return !Find(key).empty(); }
 
-  bool Member(const string &symbol) const { return Find(symbol) != kNoSymbol; }
+  bool Member(SymbolType symbol) const { return Find(symbol) != kNoSymbol; }
 
   int64 GetNthKey(ssize_t pos) const {
     if (pos < 0 || pos >= symbols_.Size()) return kNoSymbol;
@@ -150,16 +178,16 @@ class SymbolTableImpl {
     return Find(symbols_.GetSymbol(pos));
   }
 
-  const string &Name() const { return name_; }
+  const std::string &Name() const { return name_; }
 
-  void SetName(const string &new_name) { name_ = new_name; }
+  void SetName(const std::string &new_name) { name_ = new_name; }
 
-  const string &CheckSum() const {
+  const std::string &CheckSum() const {
     MaybeRecomputeCheckSum();
     return check_sum_string_;
   }
 
-  const string &LabeledCheckSum() const {
+  const std::string &LabeledCheckSum() const {
     MaybeRecomputeCheckSum();
     return labeled_check_sum_string_;
   }
@@ -175,7 +203,7 @@ class SymbolTableImpl {
   // if the checksum is up-to-date (requiring no recomputation).
   void MaybeRecomputeCheckSum() const;
 
-  string name_;
+  std::string name_;
   int64 available_key_;
   int64 dense_key_limit_;
 
@@ -188,8 +216,8 @@ class SymbolTableImpl {
   std::map<int64, int64> key_map_;
 
   mutable bool check_sum_finalized_;
-  mutable string check_sum_string_;
-  mutable string labeled_check_sum_string_;
+  mutable std::string check_sum_string_;
+  mutable std::string labeled_check_sum_string_;
   mutable Mutex check_sum_mutex_;
 };
 
@@ -207,8 +235,10 @@ class SymbolTableImpl {
 // table with the lexical representation L o G.
 class SymbolTable {
  public:
+  using SymbolType = internal::SymbolTableImpl::SymbolType;
+
   // Constructs symbol table with an optional name.
-  explicit SymbolTable(const string &name = "<unspecified>")
+  explicit SymbolTable(const std::string &name = "<unspecified>")
       : impl_(std::make_shared<internal::SymbolTableImpl>(name)) {}
 
   virtual ~SymbolTable() {}
@@ -216,18 +246,19 @@ class SymbolTable {
   // Reads a text representation of the symbol table from an istream. Pass a
   // name to give the resulting SymbolTable.
   static SymbolTable *ReadText(
-      std::istream &strm, const string &name,
+      std::istream &strm, const std::string &name,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
     auto *impl = internal::SymbolTableImpl::ReadText(strm, name, opts);
     return impl ? new SymbolTable(impl) : nullptr;
   }
 
   // Reads a text representation of the symbol table.
-  static SymbolTable *ReadText(const string &filename,
+  static SymbolTable *ReadText(
+      const std::string &filename,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
     std::ifstream strm(filename, std::ios_base::in);
     if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::ReadText: Can't open file " << filename;
+      LOG(ERROR) << "SymbolTable::ReadText: Can't open file: " << filename;
       return nullptr;
     }
     return ReadText(strm, filename, opts);
@@ -242,19 +273,18 @@ class SymbolTable {
   }
 
   // Reads a binary dump of the symbol table from a stream.
-  static SymbolTable *Read(std::istream &strm,
-                           const string &source) {
+  static SymbolTable *Read(std::istream &strm, const std::string &source) {
     SymbolTableReadOptions opts;
     opts.source = source;
     return Read(strm, opts);
   }
 
   // Reads a binary dump of the symbol table.
-  static SymbolTable *Read(const string& filename) {
+  static SymbolTable *Read(const std::string &filename) {
     std::ifstream strm(filename,
                             std::ios_base::in | std::ios_base::binary);
     if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::Read: Can't open file " << filename;
+      LOG(ERROR) << "SymbolTable::Read: Can't open file: " << filename;
       return nullptr;
     }
     return Read(strm, filename);
@@ -267,14 +297,14 @@ class SymbolTable {
 
   // Adds a symbol with given key to table. A symbol table also keeps track of
   // the last available key (highest key value in the symbol table).
-  virtual int64 AddSymbol(const string &symbol, int64 key) {
+  virtual int64 AddSymbol(SymbolType symbol, int64 key) {
     MutateCheck();
     return impl_->AddSymbol(symbol, key);
   }
 
   // Adds a symbol to the table. The associated value key is automatically
   // assigned by the symbol table.
-  virtual int64 AddSymbol(const string &symbol) {
+  virtual int64 AddSymbol(SymbolType symbol) {
     MutateCheck();
     return impl_->AddSymbol(symbol);
   }
@@ -292,31 +322,29 @@ class SymbolTable {
 
   // Return the label-agnostic MD5 check-sum for this table. All new symbols
   // added to the table will result in an updated checksum. Deprecated.
-  virtual const string &CheckSum() const { return impl_->CheckSum(); }
+  virtual const std::string &CheckSum() const { return impl_->CheckSum(); }
 
   virtual int64 GetNthKey(ssize_t pos) const { return impl_->GetNthKey(pos); }
 
   // Returns the string associated with the key; if the key is out of
   // range (<0, >max), returns an empty string.
-  virtual string Find(int64 key) const { return impl_->Find(key); }
+  virtual std::string Find(int64 key) const { return impl_->Find(key); }
 
   // Returns the key associated with the symbol; if the symbol does not exist,
   // kNoSymbol is returned.
-  virtual int64 Find(const string &symbol) const { return impl_->Find(symbol); }
+  virtual int64 Find(SymbolType symbol) const { return impl_->Find(symbol); }
 
   // Same as CheckSum(), but returns an label-dependent version.
-  virtual const string &LabeledCheckSum() const {
+  virtual const std::string &LabeledCheckSum() const {
     return impl_->LabeledCheckSum();
   }
 
   virtual bool Member(int64 key) const { return impl_->Member(key); }
 
-  virtual bool Member(const string &symbol) const {
-    return impl_->Member(symbol);
-  }
+  virtual bool Member(SymbolType symbol) const { return impl_->Member(symbol); }
 
   // Returns the name of the symbol table.
-  virtual const string &Name() const { return impl_->Name(); }
+  virtual const std::string &Name() const { return impl_->Name(); }
 
   // Returns the current number of symbols in table (not necessarily equal to
   // AvailableKey()).
@@ -328,35 +356,51 @@ class SymbolTable {
   }
 
   // Sets the name of the symbol table.
-  virtual void SetName(const string &new_name) {
+  virtual void SetName(const std::string &new_name) {
     MutateCheck();
     impl_->SetName(new_name);
   }
 
   virtual bool Write(std::ostream &strm) const { return impl_->Write(strm); }
 
-  virtual bool Write(const string &filename) const {
-    std::ofstream strm(filename,
-                             std::ios_base::out | std::ios_base::binary);
-    if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::Write: Can't open file " << filename;
-      return false;
+  virtual bool Write(const std::string &filename) const {
+    if (!filename.empty()) {
+      std::ofstream strm(filename,
+                               std::ios_base::out | std::ios_base::binary);
+      if (!strm) {
+        LOG(ERROR) << "SymbolTable::Write: Can't open file: " << filename;
+        return false;
+      }
+      if (!Write(strm)) {
+        LOG(ERROR) << "SymbolTable::Write: Write failed: " << filename;
+        return false;
+      }
+      return true;
+    } else {
+      return Write(std::cout);
     }
-    return Write(strm);
   }
 
   // Dump a text representation of the symbol table via a stream.
   virtual bool WriteText(std::ostream &strm,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) const;
 
-  // Dump an text representation of the symbol table.
-  virtual bool WriteText(const string &filename) const {
-    std::ofstream strm(filename);
-    if (!strm.good()) {
-      LOG(ERROR) << "SymbolTable::WriteText: Can't open file " << filename;
-      return false;
+  // Dump a text representation of the symbol table.
+  virtual bool WriteText(const std::string &filename) const {
+    if (!filename.empty()) {
+      std::ofstream strm(filename);
+      if (!strm) {
+        LOG(ERROR) << "SymbolTable::WriteText: Can't open file: " << filename;
+        return false;
+      }
+      if (!WriteText(strm)) {
+        LOG(ERROR) << "SymbolTable::WriteText: Write failed: " << filename;
+        return false;
+      }
+      return true;
+    } else {
+      return WriteText(std::cout);
     }
-    return WriteText(strm);
   }
 
  private:
@@ -390,7 +434,7 @@ class SymbolTableIterator {
   int64 Value() const { return key_; }
 
   // Return the string of the current symbol.
-  string Symbol() const { return table_.Find(key_); }
+  std::string Symbol() const { return table_.Find(key_); }
 
   // Advances iterator.
   void Next() {
@@ -421,8 +465,8 @@ template <class Label>
 SymbolTable *RelabelSymbolTable(const SymbolTable *table,
     const std::vector<std::pair<Label, Label>> &pairs) {
   auto *new_table = new SymbolTable(
-      table->Name().empty() ? string()
-                            : (string("relabeled_") + table->Name()));
+      table->Name().empty() ? std::string()
+                            : (std::string("relabeled_") + table->Name()));
   for (const auto &pair : pairs) {
     new_table->AddSymbol(table->Find(pair.first), pair.second);
   }
@@ -436,9 +480,9 @@ bool CompatSymbols(const SymbolTable *syms1, const SymbolTable *syms2,
 
 // Symbol Table serialization.
 
-void SymbolTableToString(const SymbolTable *table, string *result);
+void SymbolTableToString(const SymbolTable *table, std::string *result);
 
-SymbolTable *StringToSymbolTable(const string &str);
+SymbolTable *StringToSymbolTable(const std::string &str);
 
 }  // namespace fst
 
index 0c1c686..cc0d9a4 100644 (file)
@@ -10,7 +10,6 @@
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
-#include <utility>
 #include <vector>
 
 #include <fst/cache.h>
@@ -46,7 +45,7 @@ class SynchronizeFstImpl : public CacheImpl<Arc> {
   using CacheBaseImpl<CacheState<Arc>>::SetFinal;
   using CacheBaseImpl<CacheState<Arc>>::SetStart;
 
-  using String = basic_string<Label>;
+  using String = std::basic_string<Label>;
 
   struct Element {
     Element() {}
@@ -189,8 +188,7 @@ class SynchronizeFstImpl : public CacheImpl<Arc> {
   // Finds state corresponding to an element. Creates new state if element
   // is not found.
   StateId FindState(const Element &element) {
-    const auto insert_result =
-        element_map_.insert(std::make_pair(element, elements_.size()));
+    const auto insert_result = element_map_.emplace(element, elements_.size());
     if (insert_result.second) {
       elements_.push_back(element);
     }
index 7d536d9..997c241 100644 (file)
@@ -187,8 +187,8 @@ class FstTester {
   // This verifies the read/write methods.
   template <class G>
   void TestIO(const G &fst) const {
-    const string filename = FLAGS_tmpdir + "/test.fst";
-    const string aligned = FLAGS_tmpdir + "/aligned.fst";
+    const std::string filename = FLAGS_tmpdir + "/test.fst";
+    const std::string aligned = FLAGS_tmpdir + "/aligned.fst";
     {
       // write/read
       CHECK(fst.Write(filename));
index b7de665..6a35417 100644 (file)
@@ -6,9 +6,7 @@
 #ifndef FST_TEST_WEIGHT_TESTER_H_
 #define FST_TEST_WEIGHT_TESTER_H_
 
-#include <iostream>
 #include <sstream>
-
 #include <utility>
 
 #include <fst/log.h>
@@ -89,6 +87,9 @@ class WeightTester {
     // Check Power(w, 1) is w
     CHECK(Power(w1, 1) == w1);
 
+    // Check Power(w, 2) is Times(w, w)
+    CHECK(Power(w1, 2) == Times(w1, w1));
+
     // Check Power(w, 3) is Times(w, Times(w, w))
     CHECK(Power(w1, 3) == Times(w1, Times(w1, w1)));
 
@@ -160,6 +161,22 @@ class WeightTester {
 
     // Checks transitivity.
     if (w1 == w2 && w2 == w3) CHECK(w1 == w3);
+
+    // Checks that two weights are either equal or not equal.
+    CHECK((w1 == w2) ^ (w1 != w2));
+
+    if (w1 == w2) {
+      // Checks that equal weights have identical hashes.
+      CHECK(w1.Hash() == w2.Hash());
+      // Checks that equal weights are also approximately equal.
+      CHECK(ApproxEqual(w1, w2));
+    }
+
+    // Checks that weights which are not even approximately equal are also
+    // strictly unequal.
+    if (!ApproxEqual(w1, w2)) {
+      CHECK(w1 != w2);
+    }
   }
 
   // Tests binary serialization and textual I/O.
index bb2dea9..da68dc4 100644 (file)
@@ -9,7 +9,6 @@
 #define FST_UNION_WEIGHT_H_
 
 #include <cstdlib>
-
 #include <iostream>
 #include <list>
 #include <sstream>
@@ -81,16 +80,16 @@ class UnionWeight {
       <>(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() ask the empty set. Uses
+  // NoWeight() to indicate the union weight Zero() as the empty set. Uses
   // rest_ containing NoWeight() to indicate the union weight NoWeight().
   UnionWeight() : first_(W::NoWeight()) {}
 
   explicit UnionWeight(W weight) : first_(weight) {
-    if (weight == W::NoWeight()) rest_.push_back(weight);
+    if (!weight.Member()) rest_.push_back(W::NoWeight());
   }
 
   static const UnionWeight<W, O> &Zero() {
-    static const UnionWeight<W, O> zero(W::NoWeight());
+    static const UnionWeight<W, O> zero{};
     return zero;
   }
 
@@ -104,8 +103,9 @@ class UnionWeight {
     return no_weight;
   }
 
-  static const string &Type() {
-    static const string *const type = new string(W::Type() + "_union");
+  static const std::string &Type() {
+    static const std::string *const type =
+        new std::string(W::Type() + "_union");
     return *type;
   }
 
@@ -374,7 +374,7 @@ inline std::ostream &operator<<(std::ostream &ostrm,
 template <class W, class O>
 inline std::istream &operator>>(std::istream &istrm,
                                 UnionWeight<W, O> &weight) {
-  string s;
+  std::string s;
   istrm >> s;
   if (s == "EmptySet") {
     weight = UnionWeight<W, O>::Zero();
index 257099b..f3aec8a 100644 (file)
@@ -30,7 +30,6 @@ namespace fst {
 // FST.
 template <class Arc>
 void Union(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
-  using Weight = typename Arc::Weight;
   // Checks for symbol table compatibility.
   if (!CompatSymbols(fst1->InputSymbols(), fst2.InputSymbols()) ||
       !CompatSymbols(fst1->OutputSymbols(), fst2.OutputSymbols())) {
@@ -70,12 +69,12 @@ void Union(MutableFst<Arc> *fst1, const Fst<Arc> &fst2) {
     return;
   }
   if (initial_acyclic1) {
-    fst1->AddArc(start1, Arc(0, 0, Weight::One(), start2 + numstates1));
+    fst1->AddArc(start1, Arc(0, 0, start2 + numstates1));
   } else {
     const auto nstart1 = fst1->AddState();
     fst1->SetStart(nstart1);
-    fst1->AddArc(nstart1, Arc(0, 0, Weight::One(), start1));
-    fst1->AddArc(nstart1, Arc(0, 0, Weight::One(), start2 + numstates1));
+    fst1->AddArc(nstart1, Arc(0, 0, start1));
+    fst1->AddArc(nstart1, Arc(0, 0, start2 + numstates1));
   }
   fst1->SetProperties(UnionProperties(props1, props2), kFstProperties);
 }
index a89b8c1..38b3218 100644 (file)
@@ -56,7 +56,7 @@ inline std::istream &ReadType(std::istream &strm, T *t) {
 }
 
 // String case.
-inline std::istream &ReadType(std::istream &strm, string *s) {  // NOLINT
+inline std::istream &ReadType(std::istream &strm, std::string *s) {  // NOLINT
   s->clear();
   int32 ns = 0;
   strm.read(reinterpret_cast<char *>(&ns), sizeof(ns));
@@ -165,7 +165,8 @@ inline std::ostream &WriteType(std::ostream &strm, const T t) {
 }
 
 // String case.
-inline std::ostream &WriteType(std::ostream &strm, const string &s) {  // NOLINT
+inline std::ostream &WriteType(std::ostream &strm,  // NOLINT
+                               const std::string &s) {
   int32 ns = s.size();
   strm.write(reinterpret_cast<const char *>(&ns), sizeof(ns));
   return strm.write(s.data(), ns);
@@ -239,11 +240,11 @@ std::ostream &WriteType(std::ostream &strm, const std::unordered_set<T...> &c) {
 
 // Utilities for converting between int64 or Weight and string.
 
-int64 StrToInt64(const string &s, const string &src, size_t nline,
+int64 StrToInt64(const std::string &s, const std::string &src, size_t nline,
                  bool allow_negative, bool *error = nullptr);
 
 template <typename Weight>
-Weight StrToWeight(const string &s, const string &src, size_t nline) {
+Weight StrToWeight(const std::string &s, const std::string &src, size_t nline) {
   Weight w;
   std::istringstream strm(s);
   strm >> w;
@@ -256,7 +257,7 @@ Weight StrToWeight(const string &s, const string &src, size_t nline) {
 }
 
 template <typename Weight>
-void WeightToStr(Weight w, string *s) {
+void WeightToStr(Weight w, std::string *s) {
   std::ostringstream strm;
   strm.precision(9);
   strm << w;
@@ -270,7 +271,8 @@ void SplitString(char *line, const char *delim, std::vector<char *> *vec,
                  bool omit_empty_strings);
 
 template <typename I>
-bool ReadIntPairs(const string &filename, std::vector<std::pair<I, I>> *pairs,
+bool ReadIntPairs(const std::string &filename,
+                  std::vector<std::pair<I, I>> *pairs,
                   bool allow_negative = false) {
   std::ifstream strm(filename, std::ios_base::in);
   if (!strm) {
@@ -297,13 +299,13 @@ bool ReadIntPairs(const string &filename, std::vector<std::pair<I, I>> *pairs,
     if (err) return false;
     I i2 = StrToInt64(col[1], filename, nline, allow_negative, &err);
     if (err) return false;
-    pairs->push_back(std::make_pair(i1, i2));
+    pairs->emplace_back(i1, i2);
   }
   return true;
 }
 
 template <typename I>
-bool WriteIntPairs(const string &filename,
+bool WriteIntPairs(const std::string &filename,
                    const std::vector<std::pair<I, I>> &pairs) {
   std::ostream *strm = &std::cout;
   if (!filename.empty()) {
@@ -328,21 +330,21 @@ bool WriteIntPairs(const string &filename,
 // Utilities for reading/writing label pairs.
 
 template <typename Label>
-bool ReadLabelPairs(const string &filename,
+bool ReadLabelPairs(const std::string &filename,
                     std::vector<std::pair<Label, Label>> *pairs,
                     bool allow_negative = false) {
   return ReadIntPairs(filename, pairs, allow_negative);
 }
 
 template <typename Label>
-bool WriteLabelPairs(const string &filename,
+bool WriteLabelPairs(const std::string &filename,
                      const std::vector<std::pair<Label, Label>> &pairs) {
   return WriteIntPairs(filename, pairs);
 }
 
 // Utilities for converting a type name to a legal C symbol.
 
-void ConvertToLegalCSymbol(string *s);
+void ConvertToLegalCSymbol(std::string *s);
 
 // Utilities for stream I/O.
 
index 7514bc5..4f96c50 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef FST_VECTOR_FST_H_
 #define FST_VECTOR_FST_H_
 
+#include <algorithm>
 #include <string>
 #include <utility>
 #include <vector>
@@ -154,9 +155,7 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
   VectorFstBaseImpl() : start_(kNoStateId) {}
 
   ~VectorFstBaseImpl() override {
-    for (size_t s = 0; s < states_.size(); ++s) {
-      State::Destroy(states_[s], &state_alloc_);
-    }
+    for (auto *state : states_) State::Destroy(state, &state_alloc_);
   }
 
   // Copying is not permitted.
@@ -173,9 +172,12 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
   }
 
   VectorFstBaseImpl<S> &operator=(VectorFstBaseImpl<S> &&impl) noexcept {
-    states_ = std::move(impl.states_);
+    for (auto *state : states_) {
+      State::Destroy(state, &state_alloc_);
+    }
+    states_.clear();
+    std::swap(states_, impl.states_);
     start_ = impl.start_;
-    impl.states_.clear();
     impl.start_ = kNoStateId;
     return *this;
   }
@@ -202,16 +204,20 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
     states_[state]->SetFinal(std::move(weight));
   }
 
-  StateId AddState() {
-    states_.push_back(new (&state_alloc_) State(arc_alloc_));
-    return states_.size() - 1;
-  }
-
   StateId AddState(State *state) {
     states_.push_back(state);
     return states_.size() - 1;
   }
 
+  StateId AddState() { return AddState(CreateState()); }
+
+  void AddStates(size_t n) {
+    const auto curr_num_states = NumStates();
+    states_.resize(n + curr_num_states);
+    std::generate(states_.begin() + curr_num_states, states_.end(),
+                  [this] { return CreateState(); });
+  }
+
   void AddArc(StateId state, const Arc &arc) { states_[state]->AddArc(arc); }
 
   void AddArc(StateId state, Arc &&arc) {
@@ -278,7 +284,7 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
 
   void SetState(StateId state, State *vstate) { states_[state] = vstate; }
 
-  void ReserveStates(StateId n) { states_.reserve(n); }
+  void ReserveStates(size_t n) { states_.reserve(n); }
 
   void ReserveArcs(StateId state, size_t n) { states_[state]->ReserveArcs(n); }
 
@@ -297,10 +303,12 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
   }
 
  private:
-  std::vector<State *> states_;                 // States represenation.
-  StateId start_;                               // Initial state.
-  typename State::StateAllocator state_alloc_;  // For state allocation.
-  typename State::ArcAllocator arc_alloc_;      // For arc allocation.
+  State *CreateState() { return new (&state_alloc_) State(arc_alloc_); }
+
+  std::vector<State *> states_;
+  StateId start_;
+  typename State::StateAllocator state_alloc_;
+  typename State::ArcAllocator arc_alloc_;
 };
 
 // This is a VectorFstBaseImpl container that holds VectorStates and manages FST
@@ -357,6 +365,11 @@ class VectorFstImpl : public VectorFstBaseImpl<S> {
     return state;
   }
 
+  void AddStates(size_t n) {
+    BaseImpl::AddStates(n);
+    SetProperties(AddStateProperties(Properties()));
+  }
+
   void AddArc(StateId state, const Arc &arc) {
     BaseImpl::AddArc(state, arc);
     UpdatePropertiesAfterAddArc(state);
@@ -545,7 +558,7 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
 
   // Read a VectorFst from a file, returning nullptr on error; empty filename
   // reads from standard input.
-  static VectorFst<Arc, State> *Read(const string &filename) {
+  static VectorFst<Arc, State> *Read(const std::string &filename) {
     auto *impl = ImplToExpandedFst<Impl, MutableFst<Arc>>::Read(filename);
     return impl ? new VectorFst<Arc, State>(std::shared_ptr<Impl>(impl))
                 : nullptr;
@@ -555,7 +568,7 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
     return WriteFst(*this, strm, opts);
   }
 
-  bool Write(const string &filename) const override {
+  bool Write(const std::string &filename) const override {
     return Fst<Arc>::WriteFile(filename);
   }
 
index 2ea8a64..83ae7b8 100644 (file)
@@ -17,13 +17,10 @@ namespace fst {
 // Verifies that an Fst's contents are sane.
 template <class Arc>
 bool Verify(const Fst<Arc> &fst, bool allow_negative_labels = false) {
-  using StateId = typename Arc::StateId;
   const auto start = fst.Start();
   const auto *isyms = fst.InputSymbols();
   const auto *osyms = fst.OutputSymbols();
-  // Count states
-  StateId ns = 0;
-  for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) ++ns;
+  const auto ns = CountStates(fst);
   if (start == kNoStateId && ns > 0) {
     LOG(ERROR) << "Verify: FST start state ID not set";
     return false;
@@ -40,7 +37,7 @@ bool Verify(const Fst<Arc> &fst, bool allow_negative_labels = false) {
         LOG(ERROR) << "Verify: FST input label ID of arc at position " << na
                    << " of state " << state << " is negative";
         return false;
-      } else if (isyms && isyms->Find(arc.ilabel).empty()) {
+      } else if (isyms && !isyms->Member(arc.ilabel)) {
         LOG(ERROR) << "Verify: FST input label ID " << arc.ilabel
                    << " of arc at position " << na << " of state " << state
                    << " is missing from input symbol table \"" << isyms->Name()
@@ -50,7 +47,7 @@ bool Verify(const Fst<Arc> &fst, bool allow_negative_labels = false) {
         LOG(ERROR) << "Verify: FST output label ID of arc at position " << na
                    << " of state " << state << " is negative";
         return false;
-      } else if (osyms && osyms->Find(arc.olabel).empty()) {
+      } else if (osyms && !osyms->Member(arc.olabel)) {
         LOG(ERROR) << "Verify: FST output label ID " << arc.olabel
                    << " of arc at position " << na << " of state " << state
                    << " is missing from output symbol table \"" << osyms->Name()
index 2365020..236c541 100644 (file)
@@ -211,16 +211,18 @@ Weight Power(const Weight &weight, size_t n) {
 template <class Weight>
 class Adder {
  public:
-  explicit Adder(Weight w = Weight::Zero()) : sum_(w) { }
+  Adder() : sum_(Weight::Zero()) {}
+
+  explicit Adder(Weight w) : sum_(std::move(w)) {}
 
   Weight Add(const Weight &w) {
     sum_ = Plus(sum_, w);
     return sum_;
   }
 
-  Weight Sum() { return sum_; }
+  Weight Sum() const { return sum_; }
 
-  void Reset(Weight w = Weight::Zero()) { sum_ = w; }
+  void Reset(Weight w = Weight::Zero()) { sum_ = std::move(w); }
 
  private:
   Weight sum_;
@@ -239,7 +241,7 @@ struct WeightConvert {
 // Specialized weight converter to self.
 template <class W>
 struct WeightConvert<W, W> {
-  W operator()(W weight) const { return weight; }
+  constexpr W operator()(W weight) const { return weight; }
 };
 
 // General random weight generator: raises error.
@@ -347,7 +349,7 @@ class CompositeWeightReader : public internal::CompositeWeightIO {
 
 template <class T>
 inline bool CompositeWeightReader::ReadElement(T *comp, bool last) {
-  string s;
+  std::string s;
   const bool has_parens = open_paren_ != 0;
   while ((c_ != std::istream::traits_type::eof()) && !std::isspace(c_) &&
          (c_ != separator_ || depth_ > 1 || last) &&
index 5849178..27f0f6c 100644 (file)
@@ -4,5 +4,5 @@ lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.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 16:0:0
+libfst_la_LDFLAGS = -version-info 17:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index d7e5545..2a85d60 100644 (file)
@@ -349,7 +349,7 @@ libfst_la_SOURCES = compat.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 16:0:0
+libfst_la_LDFLAGS = -version-info 17:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index 43dad4c..39e6e98 100644 (file)
@@ -1,5 +1,3 @@
-// compat.cc
-//
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-// Author: riley@google.com (Michael Riley)
-//
-// \file
 // Google compatibility definitions.
 
-#include <cstring>
-#include <fst/compat.h>
+#include <cstdlib>
+#include <iostream>
 
-using namespace std;
+#include <fst/compat.h>
 
 void FailedNewHandler() {
-  cerr << "Memory allocation failed\n";
-  exit(1);
+  std::cerr << "Memory allocation failed" << std::endl;
+  std::exit(1);
 }
index 1cccd56..15bb5dd 100644 (file)
@@ -13,6 +13,7 @@
 // Google-style flag handling definitions.
 
 #include <cstring>
+#include <string>
 
 #include <fst/compat.h>
 #include <fst/flags.h>
@@ -25,10 +26,8 @@ DEFINE_bool(helpshort, false, "show brief usage information");
 DEFINE_string(tmpdir, private_tmpdir ? private_tmpdir : "/tmp",
               "temporary directory");
 
-using namespace std;
-
-static string flag_usage;
-static string prog_src;
+static std::string flag_usage;
+static std::string prog_src;
 
 // Sets prog_src to src.
 static void SetProgSrc(const char *src) {
@@ -50,32 +49,28 @@ void SetFlags(const char *usage, int *argc, char ***argv,
 
   int index = 1;
   for (; index < *argc; ++index) {
-    string argval = (*argv)[index];
+    std::string argval = (*argv)[index];
     if (argval[0] != '-' || argval == "-") break;
     while (argval[0] == '-') argval = argval.substr(1);  // Removes initial '-'.
-    string arg = argval;
-    string val = "";
+    std::string arg = argval;
+    std::string val = "";
     // Splits argval (arg=val) into arg and val.
     auto pos = argval.find("=");
-    if (pos != string::npos) {
+    if (pos != std::string::npos) {
       arg = argval.substr(0, pos);
       val = argval.substr(pos + 1);
     }
     auto bool_register = FlagRegister<bool>::GetRegister();
     if (bool_register->SetFlag(arg, val))
       continue;
-    auto string_register = FlagRegister<string>::GetRegister();
-    if (string_register->SetFlag(arg, val))
-      continue;
+    auto string_register = FlagRegister<std::string>::GetRegister();
+    if (string_register->SetFlag(arg, val)) continue;
     auto int32_register = FlagRegister<int32>::GetRegister();
-    if (int32_register->SetFlag(arg, val))
-      continue;
+    if (int32_register->SetFlag(arg, val)) continue;
     auto int64_register = FlagRegister<int64>::GetRegister();
-    if (int64_register->SetFlag(arg, val))
-      continue;
+    if (int64_register->SetFlag(arg, val)) continue;
     auto double_register = FlagRegister<double>::GetRegister();
-    if (double_register->SetFlag(arg, val))
-      continue;
+    if (double_register->SetFlag(arg, val)) continue;
     LOG(FATAL) << "SetFlags: Bad option: " << (*argv)[index];
   }
   if (remove_flags) {
@@ -96,10 +91,10 @@ void SetFlags(const char *usage, int *argc, char ***argv,
 
 // If flag is defined in file 'src' and 'in_src' true or is not
 // defined in file 'src' and 'in_src' is false, then print usage.
-static void
-ShowUsageRestrict(const std::set<pair<string, string>> &usage_set,
-                 const string &src, bool in_src, bool show_file) {
-  string old_file;
+static void ShowUsageRestrict(
+    const std::set<std::pair<std::string, std::string>> &usage_set,
+    const std::string &src, bool in_src, bool show_file) {
+  std::string old_file;
   bool file_out = false;
   bool usage_out = false;
   for (const auto &pair : usage_set) {
@@ -109,24 +104,27 @@ ShowUsageRestrict(const std::set<pair<string, string>> &usage_set,
     if ((match && !in_src) || (!match && in_src)) continue;
     if (file != old_file) {
       if (show_file) {
-        if (file_out) cout << "\n";
-           cout << "Flags from: " << file << "\n";
+        if (file_out) std::cout << std::endl;;
+        std::cout << "Flags from: " << file << std::endl;
         file_out = true;
       }
       old_file = file;
     }
-    cout << usage << "\n";
+    std::cout << usage << std::endl;
+    ;
     usage_out = true;
   }
-  if (usage_out) cout << "\n";
+  if (usage_out) std::cout << std::endl;
+  ;
 }
 
 void ShowUsage(bool long_usage) {
-  std::set<pair<string, string>> usage_set;
-  cout << flag_usage << "\n";
+  std::set<std::pair<std::string, std::string>> usage_set;
+  std::cout << flag_usage << std::endl;
+  ;
   auto bool_register = FlagRegister<bool>::GetRegister();
   bool_register->GetUsage(&usage_set);
-  auto string_register = FlagRegister<string>::GetRegister();
+  auto string_register = FlagRegister<std::string>::GetRegister();
   string_register->GetUsage(&usage_set);
   auto int32_register = FlagRegister<int32>::GetRegister();
   int32_register->GetUsage(&usage_set);
@@ -135,10 +133,13 @@ void ShowUsage(bool long_usage) {
   auto double_register = FlagRegister<double>::GetRegister();
   double_register->GetUsage(&usage_set);
   if (!prog_src.empty()) {
-    cout << "PROGRAM FLAGS:\n\n";
+    std::cout << "PROGRAM FLAGS:" << std::endl << std::endl;
+    ;
     ShowUsageRestrict(usage_set, prog_src, true, false);
   }
   if (!long_usage) return;
-  if (!prog_src.empty()) cout << "LIBRARY FLAGS:\n\n";
+  if (!prog_src.empty()) {
+    std::cout << "LIBRARY FLAGS:" << std::endl << std::endl;
+  }
   ShowUsageRestrict(usage_set, prog_src, false, true);
 }
index eb853a6..78af184 100644 (file)
@@ -1,3 +1,6 @@
+// See www.openfst.org for extensive documentation on this weighted
+// finite-state transducer library.
+//
 // Registration of common FST and arc types.
 
 #include <fst/arc.h>
index 569cfe5..0c1147e 100644 (file)
@@ -41,7 +41,7 @@ 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 string &) {
+bool IsFstHeader(std::istream &strm, const std::string &) {
   int64 pos = strm.tellg();
   bool match = true;
   int32 magic_number = 0;
@@ -55,7 +55,8 @@ bool IsFstHeader(std::istream &strm, const string &) {
 
 // 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 string &source, bool rewind) {
+bool FstHeader::Read(std::istream &strm, const std::string &source,
+                     bool rewind) {
   int64 pos = 0;
   if (rewind) pos = strm.tellg();
   int32 magic_number = 0;
@@ -82,7 +83,7 @@ bool FstHeader::Read(std::istream &strm, const string &source, bool rewind) {
 }
 
 // Writes FST magic number and FST header.
-bool FstHeader::Write(std::ostream &strm, const string &) const {
+bool FstHeader::Write(std::ostream &strm, const std::string &) const {
   WriteType(strm, kFstMagicNumber);
   WriteType(strm, fsttype_);
   WriteType(strm, arctype_);
@@ -95,7 +96,7 @@ bool FstHeader::Write(std::ostream &strm, const string &) const {
   return true;
 }
 
-string FstHeader::DebugString() const {
+std::string FstHeader::DebugString() const {
   std::ostringstream ostrm;
   ostrm << "fsttype: \"" << fsttype_ << "\" arctype: \"" << arctype_
         << "\" version: \"" << version_ << "\" flags: \"" << flags_
@@ -105,7 +106,8 @@ string FstHeader::DebugString() const {
   return ostrm.str();
 }
 
-FstReadOptions::FstReadOptions(const string &source, const FstHeader *header,
+FstReadOptions::FstReadOptions(const std::string &source,
+                               const FstHeader *header,
                                const SymbolTable *isymbols,
                                const SymbolTable *osymbols)
     : source(source),
@@ -117,7 +119,7 @@ FstReadOptions::FstReadOptions(const string &source, const FstHeader *header,
   mode = ReadMode(FLAGS_fst_read_mode);
 }
 
-FstReadOptions::FstReadOptions(const string &source,
+FstReadOptions::FstReadOptions(const std::string &source,
                                const SymbolTable *isymbols,
                                const SymbolTable *osymbols)
     : source(source),
@@ -129,14 +131,14 @@ FstReadOptions::FstReadOptions(const string &source,
   mode = ReadMode(FLAGS_fst_read_mode);
 }
 
-FstReadOptions::FileReadMode FstReadOptions::ReadMode(const string &mode) {
+FstReadOptions::FileReadMode FstReadOptions::ReadMode(const std::string &mode) {
   if (mode == "read") return READ;
   if (mode == "map") return MAP;
   LOG(ERROR) << "Unknown file read mode " << mode;
   return READ;
 }
 
-string FstReadOptions::DebugString() const {
+std::string FstReadOptions::DebugString() const {
   std::ostringstream ostrm;
   ostrm << "source: \"" << source << "\" mode: \""
         << (mode == READ ? "READ" : "MAP") << "\" read_isymbols: \""
index 12232ac..fa9f8ce 100644 (file)
@@ -4,13 +4,13 @@
 
 #include <fst/mapped-file.h>
 
-#include <errno.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <algorithm>
+#include <cerrno>
 #include <ios>
 #include <memory>
 
@@ -36,7 +36,7 @@ MappedFile::~MappedFile() {
 }
 
 MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
-                            const string &source, size_t size) {
+                            const std::string &source, size_t size) {
   const auto spos = istrm->tellg();
   VLOG(2) << "memorymap: " << (memorymap ? "true" : "false") << " source: \""
           << source << "\""
@@ -54,7 +54,7 @@ MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
           return mmf.release();
         }
       } else {
-        LOG(INFO) << "Mapping of file failed: " << strerror(errno);
+        LOG(WARNING) << "Mapping of file failed: " << strerror(errno);
       }
     }
   }
@@ -66,7 +66,7 @@ MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
   }
   // Reads the file into the buffer in chunks not larger than kMaxReadChunk.
   std::unique_ptr<MappedFile> mf(Allocate(size));
-  auto *buffer = reinterpret_cast<char *>(mf->mutable_data());
+  auto *buffer = static_cast<char *>(mf->mutable_data());
   while (size > 0) {
     const auto next_size = std::min(size, kMaxReadChunk);
     const auto current_pos = istrm->tellg();
@@ -82,7 +82,7 @@ MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
   return mf.release();
 }
 
-MappedFile *MappedFile::MapFromFileDescriptor(int fd, int pos, size_t size) {
+MappedFile *MappedFile::MapFromFileDescriptor(int fd, size_t pos, size_t size) {
   const int pagesize = sysconf(_SC_PAGESIZE);
   const off_t offset = pos % pagesize;
   const off_t upsize = size + offset;
@@ -95,19 +95,20 @@ MappedFile *MappedFile::MapFromFileDescriptor(int fd, int pos, size_t size) {
   MemoryRegion region;
   region.mmap = map;
   region.size = upsize;
-  region.data =
-      reinterpret_cast<void *>(reinterpret_cast<char *>(map) + offset);
+  region.data = static_cast<void *>(static_cast<char *>(map) + offset);
   region.offset = offset;
   return new MappedFile(region);
 }
 
-MappedFile *MappedFile::Allocate(size_t size, int align) {
+MappedFile *MappedFile::Allocate(size_t size, size_t align) {
   MemoryRegion region;
   region.data = nullptr;
   region.offset = 0;
   if (size > 0) {
+    // TODO(jrosenstock,sorenj): Use std::align() when that is no longer banned.
+    // Use std::aligned_alloc() when C++17 is allowed.
     char *buffer = static_cast<char *>(operator new(size + align));
-    size_t address = reinterpret_cast<size_t>(buffer);
+    uintptr_t address = reinterpret_cast<uintptr_t>(buffer);
     region.offset = kArchAlignment - (address % align);
     region.data = buffer + region.offset;
   }
@@ -125,7 +126,7 @@ MappedFile *MappedFile::Borrow(void *data) {
   return new MappedFile(region);
 }
 
-constexpr int MappedFile::kArchAlignment;
+constexpr size_t MappedFile::kArchAlignment;
 
 constexpr size_t MappedFile::kMaxReadChunk;
 
index 3cd276e..bd3dd92 100644 (file)
@@ -6,7 +6,8 @@
 
 #include <fst/properties.h>
 
-#include <stddef.h>
+#include <cstddef>
+#include <string>
 #include <vector>
 
 namespace fst {
index 75a06ef..cdcf1be 100644 (file)
@@ -10,7 +10,7 @@ namespace fst {
 
 SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
                               bool *right_relabel_output) {
-  // MergeSymbolTable detects several special cases.  It will return a reference
+  // MergeSymbolTable detects several special cases  It will return a reference
   // copied version of SymbolTable of left or right if either symbol table is
   // a superset of the other.
   std::unique_ptr<SymbolTable> merged(
@@ -34,34 +34,34 @@ SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
     if (right_relabel_output) *right_relabel_output = relabel;
     return right.Copy();
   }
-  // add all symbols we can from right symbol table
-  std::vector<string> conflicts;
+  // Adds all symbols we can from right symbol table.
+  std::vector<std::string> conflicts;
   for (SymbolTableIterator riter(right); !riter.Done(); riter.Next()) {
     int64 key = merged->Find(riter.Symbol());
     if (key != -1) {
-      // Symbol already exists, maybe with different value
+      // Symbol already exists, maybe with different value.
       if (key != riter.Value()) relabel = true;
       continue;
     }
-    // Symbol doesn't exist from left
+    // Symbol doesn't exist from left.
     left_has_all = false;
     if (!merged->Find(riter.Value()).empty()) {
-      // we can't add this where we want to, add it later, in order
+      // We can't add this where we want to, add it later, in order.
       conflicts.push_back(riter.Symbol());
       continue;
     }
-    // there is a hole and we can add this symbol with its id
+    // There is a hole and we can add this symbol with its ID.
     merged->AddSymbol(riter.Symbol(), riter.Value());
   }
   if (right_relabel_output) *right_relabel_output = relabel;
   if (left_has_all) return left.Copy();
-  // Add all symbols that conflicted, in order
+  // Adds all symbols that conflicted, in order.
   for (const auto &conflict : conflicts) merged->AddSymbol(conflict);
   return merged.release();
 }
 
 SymbolTable *CompactSymbolTable(const SymbolTable &syms) {
-  std::map<int64, string> sorted;
+  std::map<int64, std::string> sorted;
   SymbolTableIterator stiter(syms);
   for (; !stiter.Done(); stiter.Next()) {
     sorted[stiter.Value()] = stiter.Symbol();
@@ -72,7 +72,7 @@ SymbolTable *CompactSymbolTable(const SymbolTable &syms) {
   return compact;
 }
 
-SymbolTable *FstReadSymbols(const string &filename, bool input_symbols) {
+SymbolTable *FstReadSymbols(const std::string &filename, bool input_symbols) {
   std::ifstream in(filename, std::ios_base::in | std::ios_base::binary);
   if (!in) {
     LOG(ERROR) << "FstReadSymbols: Can't open file " << filename;
@@ -106,7 +106,7 @@ SymbolTable *FstReadSymbols(const string &filename, bool input_symbols) {
   return nullptr;
 }
 
-bool AddAuxiliarySymbols(const string &prefix, int64 start_label,
+bool AddAuxiliarySymbols(const std::string &prefix, int64 start_label,
                          int64 nlabels, SymbolTable *syms) {
   for (int64 i = 0; i < nlabels; ++i) {
     auto index = i + start_label;
index aaef368..2a659ba 100644 (file)
@@ -30,7 +30,6 @@ const int kLineLen = 8096;
 // Identifies stream data as a symbol table (and its endianity).
 static constexpr int32 kSymbolTableMagicNumber = 2125658996;
 
-
 DenseSymbolMap::DenseSymbolMap()
     : empty_(-1), buckets_(1 << 4), hash_mask_(buckets_.size() - 1) {
   std::uninitialized_fill(buckets_.begin(), buckets_.end(), empty_);
@@ -42,7 +41,7 @@ DenseSymbolMap::DenseSymbolMap(const DenseSymbolMap &other)
       buckets_(other.buckets_),
       hash_mask_(other.hash_mask_) {}
 
-std::pair<int64, bool> DenseSymbolMap::InsertOrFind(const string &key) {
+std::pair<int64, bool> DenseSymbolMap::InsertOrFind(KeyType key) {
   static constexpr float kMaxOccupancyRatio = 0.75;  // Grows when 75% full.
   if (Size() >= kMaxOccupancyRatio * buckets_.size()) {
     Rehash(buckets_.size() * 2);
@@ -59,7 +58,7 @@ std::pair<int64, bool> DenseSymbolMap::InsertOrFind(const string &key) {
   return {next, true};
 }
 
-int64 DenseSymbolMap::Find(const string &key) const {
+int64 DenseSymbolMap::Find(KeyType key) const {
   size_t idx = str_hash_(key) & hash_mask_;
   while (buckets_[idx] != empty_) {
     const auto stored_value = buckets_[idx];
@@ -74,7 +73,7 @@ void DenseSymbolMap::Rehash(size_t num_buckets) {
   hash_mask_ = buckets_.size() - 1;
   std::uninitialized_fill(buckets_.begin(), buckets_.end(), empty_);
   for (size_t i = 0; i < Size(); ++i) {
-    size_t idx = str_hash_(string(symbols_[i])) & hash_mask_;
+    size_t idx = str_hash_(symbols_[i]) & hash_mask_;
     while (buckets_[idx] != empty_) {
       idx = (idx + 1) & hash_mask_;
     }
@@ -88,7 +87,7 @@ void DenseSymbolMap::RemoveSymbol(size_t idx) {
 }
 
 SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
-                                           const string &filename,
+                                           const std::string &filename,
                                            const SymbolTableTextOptions &opts) {
   std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(filename));
   int64 nline = 0;
@@ -160,7 +159,7 @@ void SymbolTableImpl::MaybeRecomputeCheckSum() const {
   check_sum_finalized_ = true;
 }
 
-int64 SymbolTableImpl::AddSymbol(const string &symbol, int64 key) {
+int64 SymbolTableImpl::AddSymbol(SymbolType symbol, int64 key) {
   if (key == kNoSymbol) return key;
   const auto insert_key = symbols_.InsertOrFind(symbol);
   if (!insert_key.second) {
@@ -233,7 +232,7 @@ SymbolTableImpl *SymbolTableImpl::Read(
     LOG(ERROR) << "SymbolTable::Read: Read failed";
     return nullptr;
   }
-  string name;
+  std::string name;
   ReadType(strm, &name);
   std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(name));
   ReadType(strm, &impl->available_key_);
@@ -243,7 +242,7 @@ SymbolTableImpl *SymbolTableImpl::Read(
     LOG(ERROR) << "SymbolTable::Read: Read failed";
     return nullptr;
   }
-  string symbol;
+  std::string symbol;
   int64 key;
   impl->check_sum_finalized_ = false;
   for (int64 i = 0; i < size; ++i) {
@@ -323,13 +322,13 @@ bool CompatSymbols(const SymbolTable *syms1, const SymbolTable *syms2,
   }
 }
 
-void SymbolTableToString(const SymbolTable *table, string *result) {
+void SymbolTableToString(const SymbolTable *table, std::string *result) {
   std::ostringstream ostrm;
   table->Write(ostrm);
   *result = ostrm.str();
 }
 
-SymbolTable *StringToSymbolTable(const string &str) {
+SymbolTable *StringToSymbolTable(const std::string &str) {
   std::istringstream istrm(str);
   return SymbolTable::Read(istrm, SymbolTableReadOptions());
 }
index 950a628..00b8b5c 100644 (file)
@@ -4,9 +4,11 @@
 // FST utility definitions.
 
 #include <fst/util.h>
+
 #include <cctype>
 #include <sstream>
 #include <string>
+
 #include <fst/flags.h>
 #include <fst/log.h>
 #include <fst/mapped-file.h>
@@ -31,7 +33,7 @@ void SplitString(char *full, const char *delim, std::vector<char *> *vec,
   }
 }
 
-int64 StrToInt64(const string &s, const string &src, size_t nline,
+int64 StrToInt64(const std::string &s, const std::string &src, size_t nline,
                  bool allow_negative, bool *error) {
   int64 n;
   const char *cs = s.c_str();
@@ -47,7 +49,7 @@ int64 StrToInt64(const string &s, const string &src, size_t nline,
   return n;
 }
 
-void ConvertToLegalCSymbol(string *s) {
+void ConvertToLegalCSymbol(std::string *s) {
   for (auto it = s->begin(); it != s->end(); ++it) {
     if (!isalnum(*it)) {
       *it = '_';
index 9b00b12..9522f91 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 16:0:0
+libfstscript_la_LDFLAGS = -version-info 17:0:0
 endif
index dfa9733..599c005 100644 (file)
@@ -382,7 +382,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 16:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 17:0:0
 all: all-am
 
 .SUFFIXES:
index 005b413..a64dc32 100644 (file)
@@ -2,6 +2,7 @@
 // finite-state transducer library.
 
 #include <fst/script/arciterator-class.h>
+
 #include <fst/script/script-impl.h>
 
 namespace fst {
index e7fbeb5..1171f67 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/arcsort.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index d8a6788..9e17b2e 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/closure.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 0a3c9a5..c88db63 100644 (file)
@@ -1,29 +1,32 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/compile.h>
+
 #include <istream>
 #include <string>
 
-#include <fst/script/compile.h>
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void CompileFst(std::istream &istrm, const string &source, const string &dest,
-                const string &fst_type, const string &arc_type,
-                const SymbolTable *isyms, const SymbolTable *osyms,
-                const SymbolTable *ssyms, bool accep, bool ikeep, bool okeep,
-                bool nkeep, bool allow_negative_labels) {
+void CompileFst(std::istream &istrm, const std::string &source,
+                const std::string &dest, 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> fst(
       CompileFstInternal(istrm, source, fst_type, arc_type, isyms, osyms, ssyms,
                          accep, ikeep, okeep, nkeep, allow_negative_labels));
   fst->Write(dest);
 }
 
-FstClass *CompileFstInternal(std::istream &istrm, const string &source,
-                             const string &fst_type, const string &arc_type,
+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,
index fcc4028..a206093 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/compose.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index bdeba83..9a9cd28 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/concat.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 6f1ccc2..ff43568 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/connect.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index a0d1779..d14d50b 100644 (file)
@@ -1,14 +1,15 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/convert.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-FstClass *Convert(const FstClass &ifst, const string &new_type) {
+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);
index 6ffbf3e..e3ed701 100644 (file)
@@ -1,15 +1,16 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
-#include <fst/encode.h>
 #include <fst/script/decode.h>
+
+#include <fst/encode.h>
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void Decode(MutableFstClass *fst, const string &coder_fname) {
+void Decode(MutableFstClass *fst, const std::string &coder_fname) {
   DecodeArgs1 args(fst, coder_fname);
   Apply<Operation<DecodeArgs1>>("Decode", fst->ArcType(), &args);
 }
index 52bf19a..e87fa81 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/determinize.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 8161698..82b96d0 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/difference.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 30e0d75..1b484e6 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/disambiguate.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 536c9df..c63f882 100644 (file)
@@ -1,10 +1,11 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/draw.h>
+
 #include <ostream>
 #include <string>
 
-#include <fst/script/draw.h>
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
@@ -13,10 +14,11 @@ namespace script {
 
 void DrawFst(const FstClass &fst, const SymbolTable *isyms,
              const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
-             const string &title, float width, float height, bool portrait,
+             const std::string &title, float width, float height, bool portrait,
              bool vertical, float ranksep, float nodesep, int fontsize,
-             int precision, const string &float_format, bool show_weight_one,
-             std::ostream *ostrm, const string &dest) {
+             int precision, const std::string &float_format,
+             bool show_weight_one, std::ostream *ostrm,
+             const std::string &dest) {
   FstDrawerArgs args(fst, isyms, osyms, ssyms, accep, title, width, height,
                      portrait, vertical, ranksep, nodesep, fontsize, precision,
                      float_format, show_weight_one, ostrm, dest);
index 4f05450..46457d7 100644 (file)
@@ -1,16 +1,17 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/encode.h>
+
 #include <fst/script/encode.h>
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
 void Encode(MutableFstClass *fst, uint32 flags, bool reuse_encoder,
-            const string &coder_fname) {
+            const std::string &coder_fname) {
   EncodeArgs1 args(fst, flags, reuse_encoder, coder_fname);
   Apply<Operation<EncodeArgs1>>("Encode", fst->ArcType(), &args);
 }
index f93a468..6d179cc 100644 (file)
@@ -2,13 +2,15 @@
 // finite-state transducer library.
 
 #include <fst/script/encodemapper-class.h>
+
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-EncodeMapperClass::EncodeMapperClass(const string &arc_type, uint32 flags,
-                                      EncodeType type) : impl_(nullptr) {
+EncodeMapperClass::EncodeMapperClass(const std::string &arc_type, uint32 flags,
+                                     EncodeType type)
+    : impl_(nullptr) {
   InitEncodeMapperClassArgs args(flags, type, this);
   Apply<Operation<InitEncodeMapperClassArgs>>("InitEncodeMapperClass",
                                               arc_type, &args);
index df799db..1d3d3f5 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/epsnormalize.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 7d56777..3812039 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/equal.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 10bc1e7..49616c7 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/equivalent.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 6e01fda..799ea6d 100644 (file)
@@ -5,15 +5,15 @@
 // applications. Most users should use the lower-level templated versions
 // corresponding to these classes.
 
+#include <fst/script/fst-class.h>
+
 #include <istream>
 
 #include <fst/log.h>
-
 #include <fst/equal.h>
 #include <fst/fst-decl.h>
 #include <fst/reverse.h>
 #include <fst/union.h>
-#include <fst/script/fst-class.h>
 #include <fst/script/register.h>
 
 namespace fst {
@@ -30,7 +30,7 @@ REGISTER_FST_CLASSES(Log64Arc);
 namespace {
 
 template <class F>
-F *ReadFstClass(std::istream &istrm, const string &fname) {
+F *ReadFstClass(std::istream &istrm, const std::string &fname) {
   if (!istrm) {
     LOG(ERROR) << "ReadFstClass: Can't open file: " << fname;
     return nullptr;
@@ -49,7 +49,7 @@ F *ReadFstClass(std::istream &istrm, const string &fname) {
 }
 
 template <class F>
-FstClassImplBase *CreateFstClass(const string &arc_type) {
+FstClassImplBase *CreateFstClass(const std::string &arc_type) {
   static const auto *io_register =
       IORegistration<F>::Register::GetRegister();
   auto creator = io_register->GetCreator(arc_type);
@@ -77,7 +77,7 @@ FstClassImplBase *ConvertFstClass(const FstClass &other) {
 
 // FstClass methods.
 
-FstClass *FstClass::Read(const string &fname) {
+FstClass *FstClass::Read(const std::string &fname) {
   if (!fname.empty()) {
     std::ifstream istrm(fname, std::ios_base::in | std::ios_base::binary);
     return ReadFstClass<FstClass>(istrm, fname);
@@ -86,12 +86,12 @@ FstClass *FstClass::Read(const string &fname) {
   }
 }
 
-FstClass *FstClass::Read(std::istream &istrm, const string &source) {
+FstClass *FstClass::Read(std::istream &istrm, const std::string &source) {
   return ReadFstClass<FstClass>(istrm, source);
 }
 
 bool FstClass::WeightTypesMatch(const WeightClass &weight,
-                                const string &op_name) const {
+                                const std::string &op_name) const {
   if (WeightType() != weight.Type()) {
     FSTERROR() << "FST and weight with non-matching weight types passed to "
                << op_name << ": " << WeightType() << " and " << weight.Type();
@@ -102,7 +102,7 @@ bool FstClass::WeightTypesMatch(const WeightClass &weight,
 
 // MutableFstClass methods.
 
-MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
+MutableFstClass *MutableFstClass::Read(const std::string &fname, bool convert) {
   if (convert == false) {
     if (!fname.empty()) {
       std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
@@ -123,7 +123,7 @@ MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
 
 // VectorFstClass methods.
 
-VectorFstClass *VectorFstClass::Read(const string &fname) {
+VectorFstClass *VectorFstClass::Read(const std::string &fname) {
   if (!fname.empty()) {
     std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
     return ReadFstClass<VectorFstClass>(in, fname);
@@ -132,10 +132,9 @@ VectorFstClass *VectorFstClass::Read(const string &fname) {
   }
 }
 
-VectorFstClass::VectorFstClass(const string &arc_type)
+VectorFstClass::VectorFstClass(const std::string &arc_type)
     : MutableFstClass(CreateFstClass<VectorFstClass>(arc_type)) {}
 
-
 VectorFstClass::VectorFstClass(const FstClass &other)
     : MutableFstClass(ConvertFstClass<VectorFstClass>(other)) {}
 
index e231506..c3afb1d 100644 (file)
@@ -3,7 +3,7 @@
 namespace fst {
 namespace script {
 
-bool GetArcSortType(const string &str, ArcSortType *sort_type) {
+bool GetArcSortType(const std::string &str, ArcSortType *sort_type) {
   if (str == "ilabel") {
     *sort_type = ILABEL_SORT;
   } else if (str == "olabel") {
@@ -14,7 +14,7 @@ bool GetArcSortType(const string &str, ArcSortType *sort_type) {
   return true;
 }
 
-bool GetComposeFilter(const string &str, ComposeFilter *compose_filter) {
+bool GetComposeFilter(const std::string &str, ComposeFilter *compose_filter) {
   if (str == "alt_sequence") {
     *compose_filter = ALT_SEQUENCE_FILTER;
   } else if (str == "auto") {
@@ -35,7 +35,7 @@ bool GetComposeFilter(const string &str, ComposeFilter *compose_filter) {
   return true;
 }
 
-bool GetDeterminizeType(const string &str, DeterminizeType *det_type) {
+bool GetDeterminizeType(const std::string &str, DeterminizeType *det_type) {
   if (str == "functional") {
     *det_type = DETERMINIZE_FUNCTIONAL;
   } else if (str == "nonfunctional") {
@@ -48,7 +48,7 @@ bool GetDeterminizeType(const string &str, DeterminizeType *det_type) {
   return true;
 }
 
-bool GetMapType(const string &str, MapType *map_type) {
+bool GetMapType(const std::string &str, MapType *map_type) {
   if (str == "arc_sum") {
     *map_type = ARC_SUM_MAPPER;
   } else if (str == "arc_unique") {
@@ -85,7 +85,7 @@ bool GetMapType(const string &str, MapType *map_type) {
   return true;
 }
 
-bool GetRandArcSelection(const string &str, RandArcSelection *ras) {
+bool GetRandArcSelection(const std::string &str, RandArcSelection *ras) {
   if (str == "uniform") {
     *ras = UNIFORM_ARC_SELECTOR;
   } else if (str == "log_prob") {
@@ -98,7 +98,7 @@ bool GetRandArcSelection(const string &str, RandArcSelection *ras) {
   return true;
 }
 
-bool GetQueueType(const string &str, QueueType *queue_type) {
+bool GetQueueType(const std::string &str, QueueType *queue_type) {
   if (str == "auto") {
     *queue_type = AUTO_QUEUE;
   } else if (str == "fifo") {
@@ -117,7 +117,7 @@ bool GetQueueType(const string &str, QueueType *queue_type) {
   return true;
 }
 
-bool GetReplaceLabelType(const string &str, bool epsilon_on_replace,
+bool GetReplaceLabelType(const std::string &str, bool epsilon_on_replace,
                          ReplaceLabelType *rlt) {
   if (epsilon_on_replace || str == "neither") {
     *rlt = REPLACE_LABEL_NEITHER;
index 1d7c9bb..0dba623 100644 (file)
@@ -38,7 +38,7 @@ void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe) {
   ostrm << "output label multiplicity" << fstinfo.OutputLabelMultiplicity()
         << std::endl;
   ostrm.width(50);
-  string arc_type = "";
+  std::string arc_type = "";
   if (fstinfo.ArcFilterType() == "epsilon")
     arc_type = "epsilon ";
   else if (fstinfo.ArcFilterType() == "iepsilon")
index 4af5117..bcf0d6d 100644 (file)
@@ -1,25 +1,26 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/info.h>
+
 #include <string>
 
 #include <fst/script/fst-class.h>
-#include <fst/script/info.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
 void PrintFstInfo(const FstClass &fst, bool test_properties,
-                  const string &arc_filter, const string &info_type, bool pipe,
-                  bool verify) {
+                  const std::string &arc_filter, const std::string &info_type,
+                  bool pipe, bool verify) {
   InfoArgs args(fst, test_properties, arc_filter, info_type, pipe, verify);
   Apply<Operation<InfoArgs>>("PrintFstInfo", fst.ArcType(), &args);
 }
 
 void GetFstInfo(const FstClass &fst, bool test_properties,
-                const string &arc_filter, const string &info_type, bool verify,
-                FstInfo *result) {
+                const std::string &arc_filter, const std::string &info_type,
+                bool verify, FstInfo *result) {
   GetInfoArgs args(fst, test_properties, arc_filter, info_type, verify, result);
   Apply<Operation<GetInfoArgs>>("GetFstInfo", fst.ArcType(), &args);
 }
index 123b019..58dec06 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/intersect.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 1dcc68c..6276aac 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/invert.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 4d89df4..e6eb1d5 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/isomorphic.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 45ef380..f479f4c 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/map.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 9c4e59c..0fcc78c 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/minimize.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index df28dac..36ca7f0 100644 (file)
@@ -1,20 +1,21 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/print.h>
+
 #include <ostream>
 #include <string>
 
 #include <fst/script/fst-class.h>
-#include <fst/script/print.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void PrintFst(const FstClass &fst, std::ostream &ostrm, const string &dest,
+void PrintFst(const FstClass &fst, std::ostream &ostrm, const std::string &dest,
               const SymbolTable *isyms, const SymbolTable *osyms,
               const SymbolTable *ssyms, bool accept, bool show_weight_one,
-              const string &missing_sym) {
+              const std::string &missing_sym) {
   const auto sep = FLAGS_fst_field_separator.substr(0, 1);
   FstPrinterArgs args(fst, isyms, osyms, ssyms, accept, show_weight_one, &ostrm,
                       dest, sep, missing_sym);
index 32678a0..ed635fd 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/project.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 37862e2..b3042e5 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/prune.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 5b9dbea..7d75807 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/push.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 3fa518e..efe87b8 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/randequivalent.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 4da59ae..1e8c0b7 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/randgen.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index a2be47c..722a200 100644 (file)
@@ -1,18 +1,19 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/relabel.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
 
-void Relabel(MutableFstClass *ofst,
-             const SymbolTable *old_isyms, const SymbolTable *relabel_isyms,
-             const string &unknown_isymbol, bool attach_new_isyms,
+void Relabel(MutableFstClass *ofst, const SymbolTable *old_isyms,
+             const SymbolTable *relabel_isyms,
+             const std::string &unknown_isymbol, bool attach_new_isyms,
              const SymbolTable *old_osyms, const SymbolTable *relabel_osyms,
-             const string &unknown_osymbol, bool attach_new_osyms) {
+             const std::string &unknown_osymbol, bool attach_new_osyms) {
   RelabelArgs1 args(ofst, old_isyms, relabel_isyms, unknown_isymbol,
                     attach_new_isyms, old_osyms, relabel_osyms,
                     unknown_osymbol, attach_new_osyms);
index 3a92120..d5ce482 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/replace.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index e403b79..d411fee 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/reverse.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index c2306a1..3018ded 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/reweight.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 6808990..9757b00 100644 (file)
@@ -1,8 +1,9 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/fst-class.h>
 #include <fst/script/rmepsilon.h>
+
+#include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 
 namespace fst {
index 080e29d..70c9cbb 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/shortest-distance.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/shortest-distance.h>
 
 namespace fst {
 namespace script {
index cbbda63..08630e3 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/shortest-path.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/shortest-path.h>
 
 namespace fst {
 namespace script {
index 7bacd92..91d60b7 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fst/script/script-impl.h>
 #include <fst/script/stateiterator-class.h>
 
+#include <fst/script/script-impl.h>
+
 namespace fst {
 namespace script {
 
index 9599a3a..de34b81 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/synchronize.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/synchronize.h>
 
 namespace fst {
 namespace script {
index a7be721..720e2d6 100644 (file)
@@ -17,7 +17,7 @@ namespace fst {
 namespace script {
 
 // Reads vector of weights; returns true on success.
-bool ReadPotentials(const string &weight_type, const string &filename,
+bool ReadPotentials(const std::string &weight_type, const std::string &filename,
                     std::vector<WeightClass> *potentials) {
   std::ifstream istrm(filename);
   if (!istrm.good()) {
@@ -49,7 +49,7 @@ bool ReadPotentials(const string &weight_type, const string &filename,
 }
 
 // Writes vector of weights; returns true on success.
-bool WritePotentials(const string &filename,
+bool WritePotentials(const std::string &filename,
                      const std::vector<WeightClass> &potentials) {
   std::ofstream ostrm;
   if (!filename.empty()) {
index 8acd3d8..36d6fc8 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/topsort.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/topsort.h>
 
 namespace fst {
 namespace script {
index c5e8720..31b83b9 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/union.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/union.h>
 
 namespace fst {
 namespace script {
index b6e74be..848abcb 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/script/verify.h>
+
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
-#include <fst/script/verify.h>
 
 namespace fst {
 namespace script {
index 49db6bc..ab45f9c 100644 (file)
@@ -10,7 +10,8 @@ REGISTER_FST_WEIGHT(StdArc::Weight);
 REGISTER_FST_WEIGHT(LogArc::Weight);
 REGISTER_FST_WEIGHT(Log64Arc::Weight);
 
-WeightClass::WeightClass(const string &weight_type, const string &weight_str) {
+WeightClass::WeightClass(const std::string &weight_type,
+                         const std::string &weight_str) {
   WeightClassRegister *reg = WeightClassRegister::GetRegister();
   StrToWeightImplBaseT stw = reg->GetEntry(weight_type);
   if (!stw) {
@@ -21,20 +22,20 @@ WeightClass::WeightClass(const string &weight_type, const string &weight_str) {
   impl_.reset(stw(weight_str, "WeightClass", 0));
 }
 
-WeightClass WeightClass::Zero(const string &weight_type) {
+WeightClass WeightClass::Zero(const std::string &weight_type) {
   return WeightClass(weight_type, __ZERO__);
 }
 
-WeightClass WeightClass::One(const string &weight_type) {
+WeightClass WeightClass::One(const std::string &weight_type) {
   return WeightClass(weight_type, __ONE__);
 }
 
-WeightClass WeightClass::NoWeight(const string &weight_type) {
+WeightClass WeightClass::NoWeight(const std::string &weight_type) {
   return WeightClass(weight_type, __NOWEIGHT__);
 }
 
 bool WeightClass::WeightTypesMatch(const WeightClass &other,
-                                   const string &op_name) const {
+                                   const std::string &op_name) const {
   if (Type() != other.Type()) {
     FSTERROR() << "Weights with non-matching types passed to " << op_name
                << ": " << Type() << " and " << other.Type();
index c0af858..990084d 100644 (file)
@@ -27,8 +27,8 @@ struct CustomArc {
       : ilabel(i), olabel(o), weight(std::move(w)), nextstate(s) {}
   CustomArc() {}
 
-  static const string &Type() {  // Arc type name
-    static const string *const type = new string("my");
+  static const std::string &Type() {  // Arc type name
+    static const std::string *const type = new std::string("my");
     return *type;
   }
 
@@ -63,8 +63,8 @@ class CustomCompactor {
 
   bool Compatible(const Fst<A> &fst) const { return true; }
 
-  static const string &Type() {
-    static const string *const type = new string("my");
+  static const std::string &Type() {
+    static const std::string *const type = new std::string("my");
     return *type;
   }