Imported Upstream version 1.6.3 59/193959/1 upstream/1.6.3
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 28 Nov 2018 00:41:45 +0000 (09:41 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 28 Nov 2018 00:41:46 +0000 (09:41 +0900)
Change-Id: Ib236b1500b6a4290335709566d32e9522f9c943d
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
122 files changed:
Makefile.in
NEWS
README
configure
configure.ac
src/bin/fstarcsort.cc
src/bin/fstclosure.cc
src/bin/fstcompose.cc
src/bin/fstconcat.cc
src/bin/fstconnect.cc
src/bin/fstconvert.cc
src/bin/fstdeterminize.cc
src/bin/fstdifference.cc
src/bin/fstdisambiguate.cc
src/bin/fstencode.cc
src/bin/fstepsnormalize.cc
src/bin/fstintersect.cc
src/bin/fstinvert.cc
src/bin/fstmap.cc
src/bin/fstminimize.cc
src/bin/fstprint.cc
src/bin/fstproject.cc
src/bin/fstprune.cc
src/bin/fstpush.cc
src/bin/fstrandgen.cc
src/bin/fstrelabel.cc
src/bin/fstreplace.cc
src/bin/fstreverse.cc
src/bin/fstreweight.cc
src/bin/fstrmepsilon.cc
src/bin/fstshortestdistance.cc
src/bin/fstshortestpath.cc
src/bin/fstsymbols.cc
src/bin/fstsynchronize.cc
src/bin/fsttopsort.cc
src/bin/fstunion.cc
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/far/Makefile.am
src/extensions/far/Makefile.in
src/extensions/far/farscript.cc
src/extensions/far/script-impl.cc
src/extensions/far/stlist.cc
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/pdt/Makefile.am
src/extensions/pdt/Makefile.in
src/extensions/python/fst.pxd
src/extensions/python/ios.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/fst/arc-map.h
src/include/fst/arc.h
src/include/fst/cache.h
src/include/fst/compact-fst.h
src/include/fst/complement.h
src/include/fst/compose.h
src/include/fst/const-fst.h
src/include/fst/determinize.h
src/include/fst/encode.h
src/include/fst/expanded-fst.h
src/include/fst/expectation-weight.h
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/compress/gzfile.h
src/include/fst/extensions/far/farscript.h
src/include/fst/extensions/far/info.h
src/include/fst/extensions/linear/linear-fst.h
src/include/fst/extensions/mpdt/info.h
src/include/fst/extensions/ngram/ngram-fst.h
src/include/fst/extensions/pdt/info.h
src/include/fst/factor-weight.h
src/include/fst/float-weight.h
src/include/fst/fst.h
src/include/fst/heap.h
src/include/fst/lexicographic-weight.h
src/include/fst/mapped-file.h
src/include/fst/mutable-fst.h
src/include/fst/power-weight.h
src/include/fst/product-weight.h
src/include/fst/prune.h
src/include/fst/push.h
src/include/fst/randgen.h
src/include/fst/script/compile-impl.h
src/include/fst/script/draw-impl.h
src/include/fst/script/fstscript.h
src/include/fst/script/info-impl.h
src/include/fst/script/info.h
src/include/fst/signed-log-weight.h
src/include/fst/sparse-power-weight.h
src/include/fst/string-weight.h
src/include/fst/symbol-table.h
src/include/fst/union-weight.h
src/include/fst/util.h
src/include/fst/vector-fst.h
src/include/fst/weight.h
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/symbol-table-ops.cc
src/lib/util.cc
src/lib/weight.cc
src/script/Makefile.am
src/script/Makefile.in
src/script/fst-class.cc
src/script/info-impl.cc [new file with mode: 0644]
src/script/info.cc
src/script/text-io.cc
src/test/algo_test.h
src/test/fst_test.cc
src/test/fst_test.h

index 3dd0a82..59c4323 100644 (file)
@@ -83,7 +83,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(srcdir)/config.h.in \
        $(top_srcdir)/src/include/fst/config.h.in AUTHORS COPYING \
        INSTALL NEWS README ar-lib compile config.guess config.sub \
-       install-sh missing ltmain.sh
+       depcomp install-sh missing ltmain.sh
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
diff --git a/NEWS b/NEWS
index 63a70d9..1d41425 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
 OpenFst: Release 1.6
-    * Finalizes most virtual overrides (1.6.2)
+    * Removes restriction that Prune argument have commutative weights (1.6.3)
+    * Improves configuration of CompositeWeight readers and writers (1.6.3)
+    * Improves accuracy of ShortestDistance summation (1.6.3)
+    * SetFinal now "moves" its weight argument (1.6.3)
+    * Exposes ArcIterator and EncodeMapper flags in Python (1.6.3)
+    * 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)
diff --git a/README b/README
index b829aa9..8745494 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-OpenFst: Release 1.6.2
+OpenFst: Release 1.6.3
 
 OpenFst is a library for constructing, combining, optimizing, and searching
 weighted finite-state transducers (FSTs).
index b324ae2..cccaa19 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.6.2.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.6.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.6.2'
-PACKAGE_STRING='OpenFst 1.6.2'
+PACKAGE_VERSION='1.6.3'
+PACKAGE_STRING='OpenFst 1.6.3'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -1381,7 +1381,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.6.2 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.6.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1451,7 +1451,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.6.2:";;
+     short | recursive ) echo "Configuration of OpenFst 1.6.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1578,7 +1578,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.6.2
+OpenFst configure 1.6.3
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1977,7 +1977,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.6.2, which was
+It was created by OpenFst $as_me 1.6.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2840,7 +2840,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.6.2'
+ VERSION='1.6.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16752,7 +16752,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.6.2, which was
+This file was extended by OpenFst $as_me 1.6.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16818,7 +16818,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.6.2
+OpenFst config.status 1.6.3
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 1500d4b..5724113 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([OpenFst], [1.6.2], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.6.3], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
index 3a124dc..ab9b075 100644 (file)
@@ -48,7 +48,5 @@ int main(int argc, char **argv) {
 
   s::ArcSort(fst.get(), sort_type);
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index bbfc905..78ebe14 100644 (file)
@@ -37,7 +37,5 @@ int main(int argc, char **argv) {
 
   s::Closure(fst.get(), s::GetClosureType(FLAGS_closure_plus));
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index b614024..0afe013 100644 (file)
@@ -67,7 +67,5 @@ int main(int argc, char **argv) {
 
   s::Compose(*ifst1, *ifst2, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 7437221..f828a36 100644 (file)
@@ -43,7 +43,6 @@ int main(int argc, char **argv) {
   if (!fst2) return 1;
 
   s::Concat(fst1.get(), *fst2);
-  fst1->Write(out_name);
 
-  return 0;
+  return !fst1->Write(out_name);
 }
index 17bb379..2aae7e5 100644 (file)
@@ -35,7 +35,5 @@ int main(int argc, char **argv) {
 
   s::Connect(fst.get());
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index 3db00a9..08bacce 100644 (file)
@@ -36,10 +36,8 @@ int main(int argc, char **argv) {
   if (ifst->FstType() != FLAGS_fst_type) {
     std::unique_ptr<FstClass> ofst(s::Convert(*ifst, FLAGS_fst_type));
     if (!ofst) return 1;
-    ofst->Write(out_name);
+    return !ofst->Write(out_name);
   } else {
-    ifst->Write(out_name);
+    return !ifst->Write(out_name);
   }
-
-  return 0;
 }
index 040b84c..fc5a472 100644 (file)
@@ -67,7 +67,5 @@ int main(int argc, char **argv) {
 
   s::Determinize(*ifst, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 406c965..3f6dc08 100644 (file)
@@ -63,7 +63,5 @@ int main(int argc, char **argv) {
 
   s::Difference(*ifst1, *ifst2, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index b080559..310c829 100644 (file)
@@ -51,7 +51,5 @@ int main(int argc, char **argv) {
 
   s::Disambiguate(*ifst, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 4c1c2ae..4e3bb7d 100644 (file)
@@ -43,13 +43,11 @@ int main(int argc, char **argv) {
 
   if (FLAGS_decode) {
     s::Decode(fst.get(), codex_name);
-    fst->Write(out_name);
+    return !fst->Write(out_name);
   } else {
     const auto flags =
         s::GetEncodeFlags(FLAGS_encode_labels, FLAGS_encode_weights);
     s::Encode(fst.get(), flags, FLAGS_encode_reuse, codex_name);
-    fst->Write(out_name);
+    return !fst->Write(out_name);
   }
-
-  return 0;
 }
index a9fce62..bba68e8 100644 (file)
@@ -39,7 +39,5 @@ int main(int argc, char **argv) {
 
   s::EpsNormalize(*ifst, &ofst, s::GetEpsNormalizeType(FLAGS_eps_norm_output));
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 5fc9bb9..a3c34be 100644 (file)
@@ -62,7 +62,5 @@ int main(int argc, char **argv) {
 
   s::Intersect(*ifst1, *ifst2, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 30d7679..5ccf492 100644 (file)
@@ -32,7 +32,6 @@ int main(int argc, char **argv) {
   if (!fst) return 1;
 
   s::Invert(fst.get());
-  fst->Write(out_name);
 
-  return 0;
+  return !fst->Write(out_name);
 }
index db3e26a..c2fcaf9 100644 (file)
@@ -59,7 +59,5 @@ int main(int argc, char **argv) {
   std::unique_ptr<FstClass> ofst(s::Map(*ifst, map_type, FLAGS_delta,
                                         weight_param));
 
-  ofst->Write(out_name);
-
-  return 0;
+  return !ofst->Write(out_name);
 }
index 31d1900..90ede11 100644 (file)
@@ -47,11 +47,10 @@ int main(int argc, char **argv) {
   if (argc > 3) {
     std::unique_ptr<MutableFstClass> fst2(new VectorFstClass(fst1->ArcType()));
     s::Minimize(fst1.get(), fst2.get(), FLAGS_delta, FLAGS_allow_nondet);
-    fst2->Write(out2_name);
+    if (!fst2->Write(out2_name)) return 1;
   } else {
     s::Minimize(fst1.get(), nullptr, FLAGS_delta, FLAGS_allow_nondet);
   }
-  fst1->Write(out1_name);
 
-  return 0;
+  return !fst1->Write(out1_name);
 }
index 723056b..ec984cd 100644 (file)
@@ -95,11 +95,11 @@ int main(int argc, char **argv) {
               FLAGS_acceptor, FLAGS_show_weight_one, FLAGS_missing_symbol);
 
   if (isyms && !FLAGS_save_isymbols.empty()) {
-    isyms->WriteText(FLAGS_save_isymbols);
+    if (!isyms->WriteText(FLAGS_save_isymbols)) return 1;
   }
 
   if (osyms && !FLAGS_save_osymbols.empty()) {
-    osyms->WriteText(FLAGS_save_osymbols);
+    if (!osyms->WriteText(FLAGS_save_osymbols)) return 1;
   }
 
   return 0;
index 0f8a316..900094c 100644 (file)
@@ -38,7 +38,5 @@ int main(int argc, char **argv) {
 
   s::Project(fst.get(), s::GetProjectType(FLAGS_project_output));
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index 692f57f..78031b1 100644 (file)
@@ -40,11 +40,10 @@ int main(int argc, char **argv) {
       FLAGS_weight.empty() ? WeightClass::Zero(fst->WeightType())
                            : WeightClass(fst->WeightType(), FLAGS_weight);
 
-  s::PruneOptions opts(weight_threshold, FLAGS_nstate, nullptr, FLAGS_delta);
+  const s::PruneOptions opts(weight_threshold, FLAGS_nstate, nullptr,
+                             FLAGS_delta);
 
   s::Prune(fst.get(), opts);
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index f0cbe1c..41a6783 100644 (file)
@@ -52,7 +52,5 @@ int main(int argc, char **argv) {
   s::Push(*ifst, &ofst, flags, s::GetReweightType(FLAGS_to_final),
           FLAGS_delta);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index fc7f2d2..bcd273f 100644 (file)
@@ -66,7 +66,5 @@ int main(int argc, char **argv) {
                  ras, FLAGS_max_length, FLAGS_npath, FLAGS_weighted,
                  FLAGS_remove_total_weight));
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 9ef2faf..cd2653c 100644 (file)
@@ -104,7 +104,5 @@ int main(int argc, char** argv) {
     s::Relabel(fst.get(), ipairs, opairs);
   }
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index 6605189..d692acc 100644 (file)
@@ -81,7 +81,5 @@ int main(int argc, char **argv) {
   VectorFstClass ofst(ifst->ArcType());
   s::Replace(pairs, &ofst, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index f071b1e..8993574 100644 (file)
@@ -36,11 +36,9 @@ int main(int argc, char **argv) {
   std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
   if (!ifst) return 1;
 
-  VectorFstClass out(ifst->ArcType());
+  VectorFstClass ofst(ifst->ArcType());
 
-  s::Reverse(*ifst, &out, FLAGS_require_superinitial);
+  s::Reverse(*ifst, &ofst, FLAGS_require_superinitial);
 
-  out.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 2337446..88a1bb4 100644 (file)
@@ -45,7 +45,5 @@ int main(int argc, char **argv) {
 
   s::Reweight(fst.get(), potential, s::GetReweightType(FLAGS_to_final));
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index a249a58..81936ff 100644 (file)
@@ -62,7 +62,5 @@ int main(int argc, char **argv) {
 
   s::RmEpsilon(*ifst, &ofst, FLAGS_reverse, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index eb65087..0abf686 100644 (file)
@@ -67,7 +67,5 @@ int main(int argc, char **argv) {
     s::ShortestDistance(*ifst, &distance, opts);
   }
 
-  s::WritePotentials(out_name, distance);
-
-  return 0;
+  return !s::WritePotentials(out_name, distance);
 }
index d643132..2562ccf 100644 (file)
@@ -66,7 +66,5 @@ int main(int argc, char **argv) {
 
   s::ShortestPath(*ifst, &ofst, &distance, opts);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 3f1c29a..37d6895 100644 (file)
@@ -107,7 +107,5 @@ int main(int argc, char **argv) {
 
   if (FLAGS_verify && !s::Verify(*fst)) return 1;
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index f448628..0d2cd3a 100644 (file)
@@ -36,7 +36,5 @@ int main(int argc, char **argv) {
 
   s::Synchronize(*ifst, &ofst);
 
-  ofst.Write(out_name);
-
-  return 0;
+  return !ofst.Write(out_name);
 }
index 8578c93..2fcf169 100644 (file)
@@ -36,7 +36,5 @@ int main(int argc, char **argv) {
 
   if (!acyclic) LOG(WARNING) << argv[0] << ": Input FST is cyclic";
 
-  fst->Write(out_name);
-
-  return 0;
+  return !fst->Write(out_name);
 }
index 0a23b2c..856cc6c 100644 (file)
@@ -44,7 +44,5 @@ int main(int argc, char **argv) {
 
   s::Union(fst1.get(), *fst2);
 
-  fst1->Write(out_name);
-
-  return 0;
+  return !fst1->Write(out_name);
 }
index 456fca3..0da3af0 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 7:0:0
+libfstcompact_la_LDFLAGS = -version-info 8:0:0
 libfstcompact_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
index 5118933..8eac91f 100644 (file)
@@ -502,7 +502,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 7:0:0
+libfstcompact_la_LDFLAGS = -version-info 8: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 f4b4402..e8d78e1 100644 (file)
@@ -14,7 +14,7 @@ endif
 
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compress-script.cc
-libfstcompressscript_la_LDFLAGS = -version-info 7:0:0
+libfstcompressscript_la_LDFLAGS = -version-info 8:0:0
 libfstcompressscript_la_LIBADD = \
         ../../script/libfstscript.la \
         ../../lib/libfst.la -lz -lm $(DL_LIBS)
index badfc84..fe15b7b 100644 (file)
@@ -364,7 +364,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @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 7:0:0
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 8:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = \
 @HAVE_SCRIPT_TRUE@        ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lz -lm $(DL_LIBS)
index 0280e88..52328d6 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 7:0:0 -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 8:0:0 -lm $(DL_LIBS)
 libfstconst_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 const8_fst_la_SOURCES = const8-fst.cc
index 37d929b..7eeca57 100644 (file)
@@ -359,7 +359,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 7:0:0 -lm $(DL_LIBS)
+libfstconst_la_LDFLAGS = -version-info 8: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 e00d364..9637484 100644 (file)
@@ -7,13 +7,13 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 7:0:0
+libfstfar_la_LDFLAGS = -version-info 8: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 7:0:0
+libfstfarscript_la_LDFLAGS = -version-info 8:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
index 428e0c4..03402a0 100644 (file)
@@ -414,12 +414,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 7:0:0
+libfstfar_la_LDFLAGS = -version-info 8: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 7:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 8: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)
index 6c39262..17c6c46 100644 (file)
@@ -60,6 +60,13 @@ void FarInfo(const std::vector<string> &filenames, const string &arc_type,
   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) {
+  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) {
index b387f9d..6fd1331 100644 (file)
@@ -30,8 +30,7 @@ string LoadArcTypeFromFar(const string &far_fname) {
 
 string LoadArcTypeFromFst(const string &fst_fname) {
   FstHeader hdr;
-  std::ifstream in(fst_fname.c_str(),
-                        std::ios_base::in | std::ios_base::binary);
+  std::ifstream in(fst_fname, std::ios_base::in | std::ios_base::binary);
   if (!hdr.Read(in, fst_fname)) {
     LOG(ERROR) << "Error reading FST: " << fst_fname;
     return "";
index dffff3c..89e4b90 100644 (file)
@@ -9,8 +9,7 @@
 namespace fst {
 
 bool IsSTList(const string &filename) {
-  std::ifstream strm(filename.c_str(),
-                          std::ios_base::in | std::ios_base::binary);
+  std::ifstream strm(filename, std::ios_base::in | std::ios_base::binary);
   if (!strm) return false;
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
index 2563d69..7467013 100644 (file)
@@ -13,7 +13,7 @@ endif
 
 if HAVE_SCRIPT
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 7:0:0 -lm $(DL_LIBS)
+libfstlinearscript_la_LDFLAGS = -version-info 8:0:0 -lm $(DL_LIBS)
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
                                                        ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 8c3c668..dfae3f8 100644 (file)
@@ -388,7 +388,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@fstlinear_SOURCES = fstlinear.cc
 @HAVE_BIN_TRUE@fstloglinearapply_SOURCES = fstloglinearapply.cc
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 7:0:0 -lm $(DL_LIBS)
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 8:0:0 -lm $(DL_LIBS)
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                                                     ../../lib/libfst.la -lm $(DL_LIBS)
 
index 3ae65f0..ca69cba 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 7:0:0
+libfstlookahead_la_LDFLAGS = -version-info 8:0:0
 libfstlookahead_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
index afcf381..9aacf9b 100644 (file)
@@ -369,7 +369,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 7:0:0
+libfstlookahead_la_LDFLAGS = -version-info 8: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 c1c022f..22a1435 100644 (file)
@@ -20,7 +20,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 7:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 8:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 8c47d29..87c951c 100644 (file)
@@ -386,7 +386,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@mpdtreverse_SOURCES = mpdtreverse.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstmpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_SOURCES = mpdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 7:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 8:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
index fec803b..b049cab 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 7:0:0
+libfstngram_la_LDFLAGS = -version-info 8:0:0
 libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
index e6cf794..2859d23 100644 (file)
@@ -343,7 +343,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 7:0:0
+libfstngram_la_LDFLAGS = -version-info 8:0:0
 libfstngram_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 all: all-am
 
index 204ae61..1ae7541 100644 (file)
@@ -24,7 +24,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstpdtscript.la
 libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-libfstpdtscript_la_LDFLAGS = -version-info 7:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 8:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 6b9234d..a4574a9 100644 (file)
@@ -401,7 +401,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@pdtshortestpath_SOURCES = pdtshortestpath.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 7:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 8:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
index 711cf78..5b4a11d 100644 (file)
@@ -27,6 +27,7 @@ cdef extern from "<fst/util.h>" nogil:
 
 cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
+  # FST properties.
   const uint64 kExpanded
   const uint64 kMutable
   const uint64 kError
@@ -86,20 +87,23 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
   const uint64 kNegTrinaryProperties
   const uint64 kFstProperties
 
-  # Default argument constants.
-  const float kDelta
-  const int64 kNoStateId
+  # ArcIterator flags.
+  const uint32 kArcILabelValue
+  const uint32 kArcOLabelValue
+  const uint32 kArcWeightValue
+  const uint32 kArcNextStateValue
+  const uint32 kArcNoCache
+  const uint32 kArcValueFlags
+  const uint32 kArcFlags
 
   # EncodeMapper flags.
   const uint32 kEncodeLabels
   const uint32 kEncodeWeights
   const uint32 kEncodeFlags
 
-  # Push flags.
-  const uint32 kPushLabels
-  const uint32 kPushRemoveCommonAffix
-  const uint32 kPushRemoveTotalWeight
-  const uint32 kPushWeights
+  # Default argument constants.
+  const float kDelta
+  const int64 kNoStateId
 
 
   enum ClosureType:
index e4bec60..94a5818 100644 (file)
@@ -35,11 +35,11 @@ cdef extern from "<fstream>" namespace "std" nogil:
 
   cdef cppclass ifstream(istream):
 
-    ifstream(const char *)
+    ifstream(const string &)
 
   cdef cppclass ofstream(ostream):
 
-    ofstream(const char *)
+    ofstream(const string &)
 
 
 cdef extern from "<sstream>" namespace "std" nogil:
index fd503f6..6aa6eaa 100644 (file)
@@ -755,7 +755,7 @@ struct __pyx_obj_9pywrapfst_Compiler;
 struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 
-/* "fst.pxd":480
+/* "fst.pxd":484
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
@@ -764,7 +764,7 @@ struct __pyx_obj_9pywrapfst_FarWriter;
  */
 typedef std::pair<__pyx_t_10basictypes_int64,fst::script::FstClass const *>  __pyx_t_3fst_LabelFstClassPair;
 
-/* "fst.pxd":482
+/* "fst.pxd":486
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
@@ -1095,7 +1095,7 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon {
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_properties(self, uint64 props, uint64 mask) except *
+ *   cdef void _set_properties(self, uint64 props, uint64 mask)
  */
 struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final {
   int __pyx_n;
@@ -1697,7 +1697,7 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 
 
 
-/* "pywrapfst.pyx":348
+/* "pywrapfst.pyx":343
  * 
  * 
  * cdef class Weight(object):             # <<<<<<<<<<<<<<
@@ -1714,7 +1714,7 @@ struct __pyx_vtabstruct_9pywrapfst_Weight {
 static struct __pyx_vtabstruct_9pywrapfst_Weight *__pyx_vtabptr_9pywrapfst_Weight;
 
 
-/* "pywrapfst.pyx":669
+/* "pywrapfst.pyx":674
  * 
  * 
  * cdef class _SymbolTable(object):             # <<<<<<<<<<<<<<
@@ -1737,7 +1737,7 @@ struct __pyx_vtabstruct_9pywrapfst__SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtabptr_9pywrapfst__SymbolTable;
 
 
-/* "pywrapfst.pyx":821
+/* "pywrapfst.pyx":851
  * 
  * 
  * cdef class _EncodeMapperSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1751,7 +1751,7 @@ struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable;
 
 
-/* "pywrapfst.pyx":841
+/* "pywrapfst.pyx":871
  * 
  * 
  * cdef class _FstSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1765,7 +1765,7 @@ struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *__pyx_vtabptr_9pywrapfst__FstSymbolTable;
 
 
-/* "pywrapfst.pyx":860
+/* "pywrapfst.pyx":890
  * 
  * 
  * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1782,7 +1782,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
 
 
-/* "pywrapfst.pyx":911
+/* "pywrapfst.pyx":941
  * 
  * 
  * cdef class _MutableFstSymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1796,7 +1796,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTable;
 
 
-/* "pywrapfst.pyx":931
+/* "pywrapfst.pyx":952
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1810,7 +1810,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable *__pyx_vtabptr_9pywrapfst_SymbolTable;
 
 
-/* "pywrapfst.pyx":1121
+/* "pywrapfst.pyx":1135
  * 
  * 
  * cdef class SymbolTableIterator(object):             # <<<<<<<<<<<<<<
@@ -1828,7 +1828,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *__pyx_vtabptr_9pywrapfst_SymbolTableIterator;
 
 
-/* "pywrapfst.pyx":1221
+/* "pywrapfst.pyx":1217
  * 
  * 
  * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
@@ -1849,7 +1849,7 @@ struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
 
 
-/* "pywrapfst.pyx":1352
+/* "pywrapfst.pyx":1373
  * 
  * 
  * cdef class _Fst(object):             # <<<<<<<<<<<<<<
@@ -1876,12 +1876,12 @@ struct __pyx_vtabstruct_9pywrapfst__Fst {
   bool (*verify)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
   std::string (*weight_type)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
   void (*write)(struct __pyx_obj_9pywrapfst__Fst *, PyObject *, int __pyx_skip_dispatch);
-  std::string (*WriteToString)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
+  std::string (*write_to_string)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst__Fst *__pyx_vtabptr_9pywrapfst__Fst;
 
 
-/* "pywrapfst.pyx":1718
+/* "pywrapfst.pyx":1778
  * 
  * 
  * cdef class _MutableFst(_Fst):             # <<<<<<<<<<<<<<
@@ -1926,7 +1926,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFst {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFst *__pyx_vtabptr_9pywrapfst__MutableFst;
 
 
-/* "pywrapfst.pyx":2799
+/* "pywrapfst.pyx":2898
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -1940,7 +1940,7 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":2867
+/* "pywrapfst.pyx":2966
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1961,7 +1961,7 @@ struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
 
 
-/* "pywrapfst.pyx":3004
+/* "pywrapfst.pyx":3077
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1983,7 +1983,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3156
+/* "pywrapfst.pyx":3191
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -2000,7 +2000,7 @@ struct __pyx_vtabstruct_9pywrapfst_StateIterator {
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
 
 
-/* "pywrapfst.pyx":4111
+/* "pywrapfst.pyx":4132
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -2015,7 +2015,7 @@ struct __pyx_vtabstruct_9pywrapfst_Compiler {
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4237
+/* "pywrapfst.pyx":4258
  * 
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -2037,7 +2037,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4411
+/* "pywrapfst.pyx":4416
  * 
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -2430,13 +2430,13 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
 static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value);
 
 /* CIntToPy.proto */
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value);
 
 /* CIntToPy.proto */
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
 
 /* CIntToPy.proto */
-static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value);
 
 /* CIntToPy.proto */
 static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int32_t(int32_t value);
@@ -2526,9 +2526,9 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTable_copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch); /* proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename, int __pyx_skip_dispatch); /* proto*/
@@ -2567,7 +2567,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
 static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static std::string __pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 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*/
@@ -2593,10 +2593,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
 static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight *__pyx_optional_args); /* proto*/
 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); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__set_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 void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
+static void __pyx_f_9pywrapfst_11_MutableFst__set_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 void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
 static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto*/
 static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
@@ -2762,10 +2762,10 @@ static PyObject *__pyx_builtin_id;
 static PyObject *__pyx_builtin_NotImplementedError;
 static PyObject *__pyx_builtin_KeyError;
 static PyObject *__pyx_builtin_StopIteration;
-static const char __pyx_k_[] = "";
 static const char __pyx_k_g[] = "g";
 static const char __pyx_k_n[] = "n";
 static const char __pyx_k_w[] = "w";
+static const char __pyx_k__5[] = "";
 static const char __pyx_k_id[] = "id";
 static const char __pyx_k_it[] = "it";
 static const char __pyx_k_Fst[] = "Fst";
@@ -2910,6 +2910,7 @@ static const char __pyx_k_to_final[] = "to_final";
 static const char __pyx_k_tropical[] = "tropical";
 static const char __pyx_k_vertical[] = "vertical";
 static const char __pyx_k_weighted[] = "weighted";
+static const char __pyx_k_ARC_FLAGS[] = "ARC_FLAGS";
 static const char __pyx_k_Fst___new[] = "Fst.__new__";
 static const char __pyx_k_add_state[] = "add_state";
 static const char __pyx_k_add_table[] = "add_table";
@@ -2958,7 +2959,9 @@ static const char __pyx_k_push_labels[] = "push_labels";
 static const char __pyx_k_pywrapfst_2[] = "pywrapfst";
 static const char __pyx_k_unspecified[] = "<unspecified>";
 static const char __pyx_k_weight_type[] = "weight_type";
+static const char __pyx_k_ARC_NO_CACHE[] = "ARC_NO_CACHE";
 static const char __pyx_k_COACCESSIBLE[] = "COACCESSIBLE";
+static const char __pyx_k_ENCODE_FLAGS[] = "ENCODE_FLAGS";
 static const char __pyx_k_NOT_ACCEPTOR[] = "NOT_ACCEPTOR";
 static const char __pyx_k_RuntimeError[] = "RuntimeError";
 static const char __pyx_k_allow_nondet[] = "allow_nondet";
@@ -2972,21 +2975,23 @@ static const char __pyx_k_old_osymbols[] = "old_osymbols";
 static const char __pyx_k_push_weights[] = "push_weights";
 static const char __pyx_k_return_label[] = "return_label";
 static const char __pyx_k_staticmethod[] = "staticmethod";
+static const char __pyx_k_ENCODE_LABELS[] = "ENCODE_LABELS";
 static const char __pyx_k_FstIndexError[] = "FstIndexError";
 static const char __pyx_k_NO_I_EPSILONS[] = "NO_I_EPSILONS";
 static const char __pyx_k_NO_O_EPSILONS[] = "NO_O_EPSILONS";
 static const char __pyx_k_Open_failed_r[] = "Open failed: {!r}";
 static const char __pyx_k_Read_failed_r[] = "Read failed: {!r}";
 static const char __pyx_k_StopIteration[] = "StopIteration";
-static const char __pyx_k_WriteToString[] = "WriteToString";
 static const char __pyx_k_available_key[] = "available_key";
 static const char __pyx_k_encode_labels[] = "encode_labels";
 static const char __pyx_k_input_symbols[] = "input_symbols";
 static const char __pyx_k_keep_isymbols[] = "keep_isymbols";
 static const char __pyx_k_keep_osymbols[] = "keep_osymbols";
+static const char __pyx_k_ENCODE_WEIGHTS[] = "ENCODE_WEIGHTS";
 static const char __pyx_k_FST_PROPERTIES[] = "FST_PROPERTIES";
 static const char __pyx_k_INITIAL_CYCLIC[] = "INITIAL_CYCLIC";
 static const char __pyx_k_I_LABEL_SORTED[] = "I_LABEL_SORTED";
+static const char __pyx_k_Invalid_weight[] = "Invalid weight";
 static const char __pyx_k_NOT_ACCESSIBLE[] = "NOT_ACCESSIBLE";
 static const char __pyx_k_NOT_TOP_SORTED[] = "NOT_TOP_SORTED";
 static const char __pyx_k_O_LABEL_SORTED[] = "O_LABEL_SORTED";
@@ -2996,6 +3001,7 @@ static const char __pyx_k_compose_filter[] = "compose_filter";
 static const char __pyx_k_encode_weights[] = "encode_weights";
 static const char __pyx_k_output_symbols[] = "output_symbols";
 static const char __pyx_k_project_output[] = "project_output";
+static const char __pyx_k_ARC_VALUE_FLAGS[] = "ARC_VALUE_FLAGS";
 static const char __pyx_k_COPY_PROPERTIES[] = "COPY_PROPERTIES";
 static const char __pyx_k_INITIAL_ACYCLIC[] = "INITIAL_ACYCLIC";
 static const char __pyx_k_I_DETERMINISTIC[] = "I_DETERMINISTIC";
@@ -3006,6 +3012,8 @@ static const char __pyx_k_eps_norm_output[] = "eps_norm_output";
 static const char __pyx_k_show_weight_one[] = "show_weight_one";
 static const char __pyx_k_unknown_isymbol[] = "unknown_isymbol";
 static const char __pyx_k_unknown_osymbol[] = "unknown_osymbol";
+static const char __pyx_k_write_to_string[] = "write_to_string";
+static const char __pyx_k_ARC_WEIGHT_VALUE[] = "ARC_WEIGHT_VALUE";
 static const char __pyx_k_Cannot_construct[] = "Cannot construct {}";
 static const char __pyx_k_Key_out_of_order[] = "Key out of order";
 static const char __pyx_k_NOT_COACCESSIBLE[] = "NOT_COACCESSIBLE";
@@ -3013,6 +3021,8 @@ static const char __pyx_k_Operation_failed[] = "Operation failed";
 static const char __pyx_k_labeled_checksum[] = "labeled_checksum";
 static const char __pyx_k_read_from_string[] = "read_from_string";
 static const char __pyx_k_shortestdistance[] = "shortestdistance";
+static const char __pyx_k_ARC_I_LABEL_VALUE[] = "ARC_I_LABEL_VALUE";
+static const char __pyx_k_ARC_O_LABEL_VALUE[] = "ARC_O_LABEL_VALUE";
 static const char __pyx_k_BINARY_PROPERTIES[] = "BINARY_PROPERTIES";
 static const char __pyx_k_FarReader_at_0x_x[] = "<{} FarReader at 0x{:x}>";
 static const char __pyx_k_FarWriter_at_0x_x[] = "<{} FarWriter at 0x{:x}>";
@@ -3048,6 +3058,7 @@ static const char __pyx_k_remove_total_weight[] = "remove_total_weight";
 static const char __pyx_k_return_arc_labeling[] = "return_arc_labeling";
 static const char __pyx_k_subsequential_label[] = "subsequential_label";
 static const char __pyx_k_ADD_STATE_PROPERTIES[] = "ADD_STATE_PROPERTIES";
+static const char __pyx_k_ARC_NEXT_STATE_VALUE[] = "ARC_NEXT_STATE_VALUE";
 static const char __pyx_k_EXTRINSIC_PROPERTIES[] = "EXTRINSIC_PROPERTIES";
 static const char __pyx_k_EncodeMapper_at_0x_x[] = "<EncodeMapper at 0x{:x}>";
 static const char __pyx_k_Fst_read_from_string[] = "Fst.read_from_string";
@@ -3061,6 +3072,7 @@ static const char __pyx_k_DELETE_ARC_PROPERTIES[] = "DELETE_ARC_PROPERTIES";
 static const char __pyx_k_STATE_SORT_PROPERTIES[] = "STATE_SORT_PROPERTIES";
 static const char __pyx_k_StateIterator_at_0x_x[] = "<StateIterator at 0x{:x}>";
 static const char __pyx_k_SymbolTable_r_at_0x_x[] = "<SymbolTable {!r} at 0x{:x}>";
+static const char __pyx_k_Weight_type_not_found[] = "Weight type not found";
 static const char __pyx_k_allow_negative_labels[] = "allow_negative_labels";
 static const char __pyx_k_reset_fst_error_fatal[] = "_reset_fst_error_fatal";
 static const char __pyx_k_Conversion_to_r_failed[] = "Conversion to {!r} failed.";
@@ -3073,7 +3085,6 @@ static const char __pyx_k_State_index_out_of_range[] = "State index out of range
 static const char __pyx_k_ADD_SUPERFINAL_PROPERTIES[] = "ADD_SUPERFINAL_PROPERTIES";
 static const char __pyx_k_Cannot_encode_as_string_r[] = "Cannot encode as string: {!r}";
 static const char __pyx_k_Cannot_topsort_cyclic_FST[] = "Cannot topsort cyclic FST.";
-static const char __pyx_k_FstUnknownWeightTypeError[] = "FstUnknownWeightTypeError";
 static const char __pyx_k_Fst_SymbolTable_r_at_0x_x[] = "<Fst SymbolTable {!r} at 0x{:x}>";
 static const char __pyx_k_FstDeletedConstructorError[] = "FstDeletedConstructorError";
 static const char __pyx_k_MutableArcIterator_at_0x_x[] = "<MutableArcIterator at 0x{:x}>";
@@ -3098,14 +3109,20 @@ static const char __pyx_k_Incompatible_or_invalid_weight_t[] = "Incompatible or
 static const char __pyx_k_Python_interface_to_the_FST_scri[] = "Python interface to the FST scripting API.\n\nOperations which construct new FSTs are implemented as traditional functions, as\nare two-argument boolean functions like `equal` and `equivalent`. Destructive\noperations---those that mutate an FST, in place---are instance methods, as is\n`write`. Operator overloading is not used. The following example, based on\nMohri et al. 2002, shows the construction of an ASR system given a pronunciation\nlexicon L, grammar G, a transducer from context-dependent phones to\ncontext-independent phones C, and an HMM set H:\n\n  L = fst.Fst.read(\"L.fst\")\n  G = fst.Fst.read(\"G.fst\")\n  C = fst.Fst.read(\"C.fst\")\n  H = fst.Fst.read(\"H.fst\")\n  LG = fst.determinize(fst.compose(L, G))\n  CLG = fst.determinize(fst.compose(C, LG))\n  HCLG = fst.determinize(fst.compose(H, CLG))\n  HCLG.minimize()                                      # NB: works in-place.\n\nPython variables here use snake_case and constants are in all caps, minus the\nnormal `k` prefix.\n";
 static const char __pyx_k_Random_equivalence_test_encounte[] = "Random equivalence test encountered error";
 static const char __pyx_k_Unknown_random_arc_selection_typ[] = "Unknown random arc selection type: {!r}";
-static PyObject *__pyx_kp_b_;
 static PyObject *__pyx_n_s_ACCEPTOR;
 static PyObject *__pyx_n_s_ACCESSIBLE;
 static PyObject *__pyx_n_s_ACYCLIC;
 static PyObject *__pyx_n_s_ADD_ARC_PROPERTIES;
 static PyObject *__pyx_n_s_ADD_STATE_PROPERTIES;
 static PyObject *__pyx_n_s_ADD_SUPERFINAL_PROPERTIES;
+static PyObject *__pyx_n_s_ARC_FLAGS;
+static PyObject *__pyx_n_s_ARC_I_LABEL_VALUE;
+static PyObject *__pyx_n_s_ARC_NEXT_STATE_VALUE;
+static PyObject *__pyx_n_s_ARC_NO_CACHE;
+static PyObject *__pyx_n_s_ARC_O_LABEL_VALUE;
 static PyObject *__pyx_n_s_ARC_SORT_PROPERTIES;
+static PyObject *__pyx_n_s_ARC_VALUE_FLAGS;
+static PyObject *__pyx_n_s_ARC_WEIGHT_VALUE;
 static PyObject *__pyx_kp_s_ArcIterator_at_0x_x;
 static PyObject *__pyx_kp_s_Arc_at_0x_x;
 static PyObject *__pyx_n_s_BINARY_PROPERTIES;
@@ -3122,6 +3139,9 @@ static PyObject *__pyx_kp_s_Conversion_to_r_failed_2;
 static PyObject *__pyx_n_s_DELETE_ARC_PROPERTIES;
 static PyObject *__pyx_n_s_DELETE_STATE_PROPERTIES;
 static PyObject *__pyx_n_s_DOT_TSVG;
+static PyObject *__pyx_n_s_ENCODE_FLAGS;
+static PyObject *__pyx_n_s_ENCODE_LABELS;
+static PyObject *__pyx_n_s_ENCODE_WEIGHTS;
 static PyObject *__pyx_n_s_EPSILONS;
 static PyObject *__pyx_n_s_ERROR;
 static PyObject *__pyx_n_s_EXPANDED;
@@ -3139,7 +3159,6 @@ static PyObject *__pyx_n_s_FstError;
 static PyObject *__pyx_n_s_FstIOError;
 static PyObject *__pyx_n_s_FstIndexError;
 static PyObject *__pyx_n_s_FstOpError;
-static PyObject *__pyx_n_s_FstUnknownWeightTypeError;
 static PyObject *__pyx_kp_s_Fst_SymbolTable_r_at_0x_x;
 static PyObject *__pyx_n_s_Fst___new;
 static PyObject *__pyx_kp_s_Fst_arc_type_standard_Construct;
@@ -3159,6 +3178,7 @@ static PyObject *__pyx_kp_s_Incompatible_or_invalid_weight;
 static PyObject *__pyx_kp_s_Incompatible_or_invalid_weight_t;
 static PyObject *__pyx_n_s_IndexError;
 static PyObject *__pyx_kp_s_Invalid_operator_r;
+static PyObject *__pyx_kp_s_Invalid_weight;
 static PyObject *__pyx_n_s_KeyError;
 static PyObject *__pyx_kp_s_Key_out_of_order;
 static PyObject *__pyx_n_s_MUTABLE;
@@ -3224,9 +3244,10 @@ static PyObject *__pyx_n_s_WEIGHTED;
 static PyObject *__pyx_n_s_WEIGHTED_CYCLES;
 static PyObject *__pyx_n_s_WEIGHT_INVARIANT_PROPERTIES;
 static PyObject *__pyx_kp_s_Weight_at_0x_x;
-static PyObject *__pyx_n_s_WriteToString;
+static PyObject *__pyx_kp_s_Weight_type_not_found;
 static PyObject *__pyx_kp_s_Write_failed_r;
 static PyObject *__pyx_n_s_Zero;
+static PyObject *__pyx_kp_b__5;
 static PyObject *__pyx_n_s_acceptor;
 static PyObject *__pyx_n_s_add;
 static PyObject *__pyx_n_s_add_state;
@@ -3434,6 +3455,7 @@ static PyObject *__pyx_n_s_weighted;
 static PyObject *__pyx_n_s_width;
 static PyObject *__pyx_n_s_write;
 static PyObject *__pyx_n_s_write_text;
+static PyObject *__pyx_n_s_write_to_string;
 static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
@@ -3455,10 +3477,10 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4available_key(struct __pyx_
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static int __pyx_pf_9pywrapfst_12_SymbolTable_14__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static int __pyx_pf_9pywrapfst_12_SymbolTable_18__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_20name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
@@ -3518,7 +3540,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36text(struct __pyx_obj_9pywrapfst__F
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_38verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_40weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4_Fst_42write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_44WriteToString(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write_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 */
@@ -3545,10 +3567,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
 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, bool __pyx_v_connect, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* 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_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_54set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_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_58set_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_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_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_cls, PyObject *__pyx_v_arc_type); /* proto */
@@ -3579,17 +3601,15 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_ifst, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_6__next__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_12next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_22set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_24value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_6flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_12reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
@@ -3667,90 +3687,94 @@ static PyObject *__pyx_tp_new_9pywrapfst_FarReader(PyTypeObject *t, PyObject *a,
 static PyObject *__pyx_tp_new_9pywrapfst_FarWriter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_int_0;
 static PyObject *__pyx_int_neg_1;
-static float __pyx_k__11;
-static float __pyx_k__12;
-static float __pyx_k__13;
-static __pyx_t_10basictypes_int64 __pyx_k__14;
 static float __pyx_k__15;
-static __pyx_t_10basictypes_int64 __pyx_k__16;
+static float __pyx_k__16;
 static float __pyx_k__17;
-static float __pyx_k__18;
+static __pyx_t_10basictypes_int64 __pyx_k__18;
+static float __pyx_k__19;
+static __pyx_t_10basictypes_int64 __pyx_k__20;
+static float __pyx_k__21;
 static float __pyx_k__22;
-static __pyx_t_10basictypes_int64 __pyx_k__23;
-static float __pyx_k__24;
-static __pyx_t_10basictypes_int64 __pyx_k__25;
-static float __pyx_k__34;
-static float __pyx_k__35;
-static float __pyx_k__36;
-static __pyx_t_10basictypes_int64 __pyx_k__37;
+static float __pyx_k__26;
+static __pyx_t_10basictypes_int64 __pyx_k__27;
+static float __pyx_k__28;
+static __pyx_t_10basictypes_int64 __pyx_k__29;
 static float __pyx_k__38;
-static __pyx_t_10basictypes_int64 __pyx_k__39;
+static float __pyx_k__39;
 static float __pyx_k__40;
-static float __pyx_k__41;
-static float __pyx_k__43;
+static __pyx_t_10basictypes_int64 __pyx_k__41;
+static float __pyx_k__42;
+static __pyx_t_10basictypes_int64 __pyx_k__43;
 static float __pyx_k__44;
-static __pyx_t_10basictypes_int64 __pyx_k__45;
-static float __pyx_k__46;
+static float __pyx_k__45;
 static float __pyx_k__47;
-static __pyx_t_10basictypes_int32 __pyx_k__48;
-static __pyx_t_10basictypes_int32 __pyx_k__50;
+static float __pyx_k__48;
+static __pyx_t_10basictypes_int64 __pyx_k__49;
+static float __pyx_k__50;
 static float __pyx_k__51;
-static __pyx_t_10basictypes_int64 __pyx_k__52;
-static float __pyx_k__53;
-static __pyx_t_10basictypes_int64 __pyx_k__54;
+static __pyx_t_10basictypes_int32 __pyx_k__52;
+static __pyx_t_10basictypes_int32 __pyx_k__54;
 static float __pyx_k__55;
 static __pyx_t_10basictypes_int64 __pyx_k__56;
 static float __pyx_k__57;
 static __pyx_t_10basictypes_int64 __pyx_k__58;
-static std::string __pyx_k__59;
-static std::string __pyx_k__60;
+static float __pyx_k__59;
+static __pyx_t_10basictypes_int64 __pyx_k__60;
+static float __pyx_k__61;
+static __pyx_t_10basictypes_int64 __pyx_k__62;
+static std::string __pyx_k__63;
+static std::string __pyx_k__64;
+static PyObject *__pyx_tuple_;
 static PyObject *__pyx_tuple__2;
 static PyObject *__pyx_tuple__3;
 static PyObject *__pyx_tuple__4;
-static PyObject *__pyx_tuple__5;
 static PyObject *__pyx_tuple__6;
 static PyObject *__pyx_tuple__7;
 static PyObject *__pyx_tuple__8;
 static PyObject *__pyx_tuple__9;
 static PyObject *__pyx_tuple__10;
-static PyObject *__pyx_tuple__19;
-static PyObject *__pyx_tuple__20;
-static PyObject *__pyx_tuple__21;
-static PyObject *__pyx_tuple__26;
-static PyObject *__pyx_tuple__27;
-static PyObject *__pyx_tuple__28;
-static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
 static PyObject *__pyx_tuple__30;
 static PyObject *__pyx_tuple__31;
 static PyObject *__pyx_tuple__32;
 static PyObject *__pyx_tuple__33;
-static PyObject *__pyx_tuple__42;
-static PyObject *__pyx_tuple__49;
-static PyObject *__pyx_tuple__61;
-static PyObject *__pyx_tuple__62;
-static PyObject *__pyx_tuple__63;
-static PyObject *__pyx_tuple__64;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__46;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__65;
 static PyObject *__pyx_tuple__66;
+static PyObject *__pyx_tuple__67;
 static PyObject *__pyx_tuple__68;
 static PyObject *__pyx_tuple__70;
 static PyObject *__pyx_tuple__72;
 static PyObject *__pyx_tuple__74;
-static PyObject *__pyx_tuple__75;
-static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__76;
 static PyObject *__pyx_tuple__78;
-static PyObject *__pyx_tuple__80;
+static PyObject *__pyx_tuple__79;
 static PyObject *__pyx_tuple__81;
-static PyObject *__pyx_codeobj__65;
-static PyObject *__pyx_codeobj__67;
+static PyObject *__pyx_tuple__82;
+static PyObject *__pyx_tuple__84;
+static PyObject *__pyx_tuple__85;
 static PyObject *__pyx_codeobj__69;
 static PyObject *__pyx_codeobj__71;
 static PyObject *__pyx_codeobj__73;
-static PyObject *__pyx_codeobj__76;
-static PyObject *__pyx_codeobj__79;
-static PyObject *__pyx_codeobj__82;
+static PyObject *__pyx_codeobj__75;
+static PyObject *__pyx_codeobj__77;
+static PyObject *__pyx_codeobj__80;
 static PyObject *__pyx_codeobj__83;
+static PyObject *__pyx_codeobj__86;
+static PyObject *__pyx_codeobj__87;
 
-/* "pywrapfst.pyx":159
+/* "pywrapfst.pyx":154
  * 
  * 
  * cdef string tostring(data, encoding="utf8") except *:             # <<<<<<<<<<<<<<
@@ -3778,7 +3802,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
     }
   }
 
-  /* "pywrapfst.pyx":180
+  /* "pywrapfst.pyx":175
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -3789,18 +3813,18 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":181
+    /* "pywrapfst.pyx":176
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):
  *     return data             # <<<<<<<<<<<<<<
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 176, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":180
+    /* "pywrapfst.pyx":175
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -3809,7 +3833,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
  */
   }
 
-  /* "pywrapfst.pyx":182
+  /* "pywrapfst.pyx":177
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -3820,14 +3844,14 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":183
+    /* "pywrapfst.pyx":178
  *     return data
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)             # <<<<<<<<<<<<<<
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))
  * 
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -3840,13 +3864,13 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_encoding); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_encoding); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 178, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_encoding};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 178, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
@@ -3854,30 +3878,30 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_encoding};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 178, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
       #endif
       {
-        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 183, __pyx_L1_error)
+        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 178, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_INCREF(__pyx_v_encoding);
         __Pyx_GIVEREF(__pyx_v_encoding);
         PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_encoding);
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 178, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       }
     }
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 183, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 178, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":182
+    /* "pywrapfst.pyx":177
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -3886,16 +3910,16 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
  */
   }
 
-  /* "pywrapfst.pyx":184
+  /* "pywrapfst.pyx":179
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 184, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 179, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 184, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 179, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __pyx_t_8 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -3908,13 +3932,13 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
     }
   }
   if (!__pyx_t_8) {
-    __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_data); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 184, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_data); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 179, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_6)) {
       PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_data};
-      __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_GOTREF(__pyx_t_7);
     } else
@@ -3922,19 +3946,19 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
       PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_data};
-      __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_GOTREF(__pyx_t_7);
     } else
     #endif
     {
-      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
       __Pyx_INCREF(__pyx_v_data);
       __Pyx_GIVEREF(__pyx_v_data);
       PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_data);
-      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
     }
@@ -3951,14 +3975,14 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
     }
   }
   if (!__pyx_t_6) {
-    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 184, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 179, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_GOTREF(__pyx_t_4);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_5)) {
       PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_7};
-      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
@@ -3967,20 +3991,20 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
       PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_7};
-      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     } else
     #endif
     {
-      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_6); __pyx_t_6 = NULL;
       __Pyx_GIVEREF(__pyx_t_7);
       PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_7);
       __pyx_t_7 = 0;
-      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 184, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 179, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
     }
@@ -3988,9 +4012,9 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
   __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, 184, __pyx_L1_error)
+  __PYX_ERR(0, 179, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":159
+  /* "pywrapfst.pyx":154
  * 
  * 
  * cdef string tostring(data, encoding="utf8") except *:             # <<<<<<<<<<<<<<
@@ -4012,7 +4036,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data, struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":187
+/* "pywrapfst.pyx":182
  * 
  * 
  * cdef string weighttostring(data, encoding="utf8") except *:             # <<<<<<<<<<<<<<
@@ -4040,7 +4064,7 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
     }
   }
 
-  /* "pywrapfst.pyx":211
+  /* "pywrapfst.pyx":206
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4051,18 +4075,18 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":212
+    /* "pywrapfst.pyx":207
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):
  *     return data             # <<<<<<<<<<<<<<
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 212, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 207, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":211
+    /* "pywrapfst.pyx":206
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4071,7 +4095,7 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
  */
   }
 
-  /* "pywrapfst.pyx":213
+  /* "pywrapfst.pyx":208
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4082,14 +4106,14 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":214
+    /* "pywrapfst.pyx":209
  *     return data
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)             # <<<<<<<<<<<<<<
  *   elif isinstance(data, numbers.Number):
  *     return str(data).encode(encoding)
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 214, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 209, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4102,13 +4126,13 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_encoding); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 214, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_encoding); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 209, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_encoding};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 214, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 209, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
@@ -4116,30 +4140,30 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_encoding};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 214, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 209, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
       #endif
       {
-        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 214, __pyx_L1_error)
+        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 209, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_INCREF(__pyx_v_encoding);
         __Pyx_GIVEREF(__pyx_v_encoding);
         PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_encoding);
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 214, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 209, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       }
     }
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 214, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 209, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":213
+    /* "pywrapfst.pyx":208
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4148,39 +4172,39 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
  */
   }
 
-  /* "pywrapfst.pyx":215
+  /* "pywrapfst.pyx":210
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)
  *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
  *     return str(data).encode(encoding)
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))
  */
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 210, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 215, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 210, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_1 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(0, 215, __pyx_L1_error)
+  __pyx_t_1 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(0, 210, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":216
+    /* "pywrapfst.pyx":211
  *     return data.encode(encoding)
  *   elif isinstance(data, numbers.Number):
  *     return str(data).encode(encoding)             # <<<<<<<<<<<<<<
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))
  * 
  */
-    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 216, __pyx_L1_error)
+    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 211, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_INCREF(__pyx_v_data);
     __Pyx_GIVEREF(__pyx_v_data);
     PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_data);
-    __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 216, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 211, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 216, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 211, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -4194,13 +4218,13 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_encoding); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 216, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_encoding); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 211, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_encoding};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 216, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 211, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -4208,30 +4232,30 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_encoding};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 216, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 211, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 216, __pyx_L1_error)
+        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 211, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_encoding);
         __Pyx_GIVEREF(__pyx_v_encoding);
         PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_encoding);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 216, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 211, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       }
     }
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 216, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 211, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":215
+    /* "pywrapfst.pyx":210
  *   elif isinstance(data, unicode):
  *     return data.encode(encoding)
  *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
@@ -4240,16 +4264,16 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
  */
   }
 
-  /* "pywrapfst.pyx":217
+  /* "pywrapfst.pyx":212
  *   elif isinstance(data, numbers.Number):
  *     return str(data).encode(encoding)
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 217, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 212, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 217, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 212, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __pyx_t_8 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -4262,13 +4286,13 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
     }
   }
   if (!__pyx_t_8) {
-    __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 217, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 212, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_7)) {
       PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_data};
-      __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_GOTREF(__pyx_t_6);
     } else
@@ -4276,19 +4300,19 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
       PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_data};
-      __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
       __Pyx_GOTREF(__pyx_t_6);
     } else
     #endif
     {
-      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
       __Pyx_INCREF(__pyx_v_data);
       __Pyx_GIVEREF(__pyx_v_data);
       PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_data);
-      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
     }
@@ -4305,14 +4329,14 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
     }
   }
   if (!__pyx_t_7) {
-    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 217, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 212, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_GOTREF(__pyx_t_5);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -4321,20 +4345,20 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     #endif
     {
-      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
       __pyx_t_6 = 0;
-      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 217, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 212, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
     }
@@ -4342,9 +4366,9 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_Raise(__pyx_t_5, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __PYX_ERR(0, 217, __pyx_L1_error)
+  __PYX_ERR(0, 212, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":187
+  /* "pywrapfst.pyx":182
  * 
  * 
  * cdef string weighttostring(data, encoding="utf8") except *:             # <<<<<<<<<<<<<<
@@ -4366,7 +4390,7 @@ static std::string __pyx_f_9pywrapfst_weighttostring(PyObject *__pyx_v_data, str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":220
+/* "pywrapfst.pyx":215
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4388,7 +4412,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_compose_filter", 0);
 
-  /* "pywrapfst.pyx":241
+  /* "pywrapfst.pyx":236
  *   """
  *   cdef fst.ComposeFilter compose_filter_enum
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
@@ -4398,26 +4422,26 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_t_1 = ((!(fst::script::GetComposeFilter(__pyx_v_compose_filter, (&__pyx_v_compose_filter_enum)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":242
+    /* "pywrapfst.pyx":237
  *   cdef fst.ComposeFilter compose_filter_enum
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):
  *     raise FstArgError("Unknown compose filter type: {!r}".format(             # <<<<<<<<<<<<<<
  *         compose_filter))
  *   return compose_filter_enum
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 242, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 237, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_compose_filter_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 242, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_compose_filter_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 237, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
 
-    /* "pywrapfst.pyx":243
+    /* "pywrapfst.pyx":238
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):
  *     raise FstArgError("Unknown compose filter type: {!r}".format(
  *         compose_filter))             # <<<<<<<<<<<<<<
  *   return compose_filter_enum
  * 
  */
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 243, __pyx_L1_error)
+    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4430,14 +4454,14 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 242, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 237, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -4446,20 +4470,20 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4476,14 +4500,14 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 242, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_2);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -4492,20 +4516,20 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 242, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4513,9 +4537,9 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
     __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, 242, __pyx_L1_error)
+    __PYX_ERR(0, 237, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":241
+    /* "pywrapfst.pyx":236
  *   """
  *   cdef fst.ComposeFilter compose_filter_enum
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
@@ -4524,7 +4548,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
  */
   }
 
-  /* "pywrapfst.pyx":244
+  /* "pywrapfst.pyx":239
  *     raise FstArgError("Unknown compose filter type: {!r}".format(
  *         compose_filter))
  *   return compose_filter_enum             # <<<<<<<<<<<<<<
@@ -4534,7 +4558,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_r = __pyx_v_compose_filter_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":220
+  /* "pywrapfst.pyx":215
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4558,7 +4582,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":247
+/* "pywrapfst.pyx":242
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4580,7 +4604,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_determinize_type", 0);
 
-  /* "pywrapfst.pyx":263
+  /* "pywrapfst.pyx":258
  *   """
  *   cdef fst.DeterminizeType det_type_enum
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
@@ -4590,18 +4614,18 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_t_1 = ((!(fst::script::GetDeterminizeType(__pyx_v_det_type, (&__pyx_v_det_type_enum)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":264
+    /* "pywrapfst.pyx":259
  *   cdef fst.DeterminizeType det_type_enum
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))             # <<<<<<<<<<<<<<
  *   return det_type_enum
  * 
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 264, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 259, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 264, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 259, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 264, __pyx_L1_error)
+    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 259, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4614,14 +4638,14 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -4630,20 +4654,20 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4660,14 +4684,14 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 264, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 259, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_2);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -4676,20 +4700,20 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 264, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 259, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4697,9 +4721,9 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
     __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, 264, __pyx_L1_error)
+    __PYX_ERR(0, 259, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":263
+    /* "pywrapfst.pyx":258
  *   """
  *   cdef fst.DeterminizeType det_type_enum
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
@@ -4708,7 +4732,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
  */
   }
 
-  /* "pywrapfst.pyx":265
+  /* "pywrapfst.pyx":260
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
  *   return det_type_enum             # <<<<<<<<<<<<<<
@@ -4718,7 +4742,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_r = __pyx_v_det_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":247
+  /* "pywrapfst.pyx":242
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4742,7 +4766,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":268
+/* "pywrapfst.pyx":263
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4764,7 +4788,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_queue_type", 0);
 
-  /* "pywrapfst.pyx":287
+  /* "pywrapfst.pyx":282
  *   """
  *   cdef fst.QueueType queue_type_enum
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
@@ -4774,18 +4798,18 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_t_1 = ((!(fst::script::GetQueueType(__pyx_v_queue_type, (&__pyx_v_queue_type_enum)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":288
+    /* "pywrapfst.pyx":283
  *   cdef fst.QueueType queue_type_enum
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):
  *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))             # <<<<<<<<<<<<<<
  *   return queue_type_enum
  * 
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 288, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 283, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_queue_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 288, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_queue_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 283, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 288, __pyx_L1_error)
+    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 283, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4798,14 +4822,14 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -4814,20 +4838,20 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4844,14 +4868,14 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_2);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -4860,20 +4884,20 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -4881,9 +4905,9 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
     __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, 288, __pyx_L1_error)
+    __PYX_ERR(0, 283, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":287
+    /* "pywrapfst.pyx":282
  *   """
  *   cdef fst.QueueType queue_type_enum
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
@@ -4892,7 +4916,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
  */
   }
 
-  /* "pywrapfst.pyx":289
+  /* "pywrapfst.pyx":284
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):
  *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))
  *   return queue_type_enum             # <<<<<<<<<<<<<<
@@ -4902,7 +4926,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_r = __pyx_v_queue_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":268
+  /* "pywrapfst.pyx":263
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4926,7 +4950,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":292
+/* "pywrapfst.pyx":287
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -4948,7 +4972,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_rand_arc_selection", 0);
 
-  /* "pywrapfst.pyx":312
+  /* "pywrapfst.pyx":307
  *   """
  *   cdef fst.RandArcSelection select_enum
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
@@ -4958,18 +4982,18 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_t_1 = ((!(fst::script::GetRandArcSelection(__pyx_v_select, (&__pyx_v_select_enum)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":313
+    /* "pywrapfst.pyx":308
  *   cdef fst.RandArcSelection select_enum
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):
  *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))             # <<<<<<<<<<<<<<
  *   return select_enum
  * 
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 313, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 308, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_random_arc_selection_typ, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 313, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_random_arc_selection_typ, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 308, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 313, __pyx_L1_error)
+    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 308, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4982,14 +5006,14 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 313, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -4998,20 +5022,20 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -5028,14 +5052,14 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_2);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -5044,20 +5068,20 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -5065,9 +5089,9 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
     __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, 313, __pyx_L1_error)
+    __PYX_ERR(0, 308, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":312
+    /* "pywrapfst.pyx":307
  *   """
  *   cdef fst.RandArcSelection select_enum
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
@@ -5076,7 +5100,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
  */
   }
 
-  /* "pywrapfst.pyx":314
+  /* "pywrapfst.pyx":309
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):
  *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))
  *   return select_enum             # <<<<<<<<<<<<<<
@@ -5086,7 +5110,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_r = __pyx_v_select_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":292
+  /* "pywrapfst.pyx":287
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -5110,7 +5134,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":317
+/* "pywrapfst.pyx":312
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5132,7 +5156,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_replace_label_type", 0);
 
-  /* "pywrapfst.pyx":338
+  /* "pywrapfst.pyx":333
  *   """
  *   cdef fst.ReplaceLabelType replace_label_type_enum
  *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
@@ -5142,26 +5166,26 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_t_1 = ((!(fst::script::GetReplaceLabelType(__pyx_v_replace_label_type, __pyx_v_epsilon_on_replace, (&__pyx_v_replace_label_type_enum)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":340
+    /* "pywrapfst.pyx":335
  *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,
  *                                  addr(replace_label_type_enum)):
  *     raise FstArgError("Unknown replace label type: {!r}".format(             # <<<<<<<<<<<<<<
  *                       replace_label_type))
  *   return replace_label_type_enum
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 340, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 335, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_replace_label_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 340, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_replace_label_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 335, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
 
-    /* "pywrapfst.pyx":341
+    /* "pywrapfst.pyx":336
  *                                  addr(replace_label_type_enum)):
  *     raise FstArgError("Unknown replace label type: {!r}".format(
  *                       replace_label_type))             # <<<<<<<<<<<<<<
  *   return replace_label_type_enum
  * 
  */
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 341, __pyx_L1_error)
+    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 336, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -5174,14 +5198,14 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -5190,20 +5214,20 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -5220,14 +5244,14 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 335, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_2);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -5236,20 +5260,20 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 340, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 335, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -5257,9 +5281,9 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
     __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, 340, __pyx_L1_error)
+    __PYX_ERR(0, 335, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":338
+    /* "pywrapfst.pyx":333
  *   """
  *   cdef fst.ReplaceLabelType replace_label_type_enum
  *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
@@ -5268,7 +5292,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
  */
   }
 
-  /* "pywrapfst.pyx":342
+  /* "pywrapfst.pyx":337
  *     raise FstArgError("Unknown replace label type: {!r}".format(
  *                       replace_label_type))
  *   return replace_label_type_enum             # <<<<<<<<<<<<<<
@@ -5278,7 +5302,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_r = __pyx_v_replace_label_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":317
+  /* "pywrapfst.pyx":312
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5302,7 +5326,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":368
+/* "pywrapfst.pyx":363
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5336,7 +5360,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":369
+  /* "pywrapfst.pyx":364
  * 
  *   def __repr__(self):
  *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),             # <<<<<<<<<<<<<<
@@ -5344,34 +5368,34 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Weight_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Weight_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 364, __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 '%s'", "type");
-    __PYX_ERR(0, 369, __pyx_L1_error)
+    __PYX_ERR(0, 364, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 369, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 364, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-    __PYX_ERR(0, 369, __pyx_L1_error)
+    __PYX_ERR(0, 364, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 369, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 364, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
 
-  /* "pywrapfst.pyx":370
+  /* "pywrapfst.pyx":365
  *   def __repr__(self):
  *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),
  *                                              id(self))             # <<<<<<<<<<<<<<
  * 
  *   def __str__(self):
  */
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 370, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 365, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 370, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 365, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -5389,7 +5413,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[4] = {__pyx_t_5, __pyx_t_3, __pyx_t_4, __pyx_t_6};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 364, __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;
@@ -5400,7 +5424,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[4] = {__pyx_t_5, __pyx_t_3, __pyx_t_4, __pyx_t_6};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 364, __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;
@@ -5409,7 +5433,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   } else
   #endif
   {
-    __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 364, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
     if (__pyx_t_5) {
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -5423,7 +5447,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
     __pyx_t_3 = 0;
     __pyx_t_4 = 0;
     __pyx_t_6 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 364, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   }
@@ -5432,7 +5456,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":368
+  /* "pywrapfst.pyx":363
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5457,7 +5481,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":372
+/* "pywrapfst.pyx":367
  *                                              id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5484,7 +5508,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":373
+  /* "pywrapfst.pyx":368
  * 
  *   def __str__(self):
  *     return self.to_string()             # <<<<<<<<<<<<<<
@@ -5494,15 +5518,15 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-    __PYX_ERR(0, 373, __pyx_L1_error)
+    __PYX_ERR(0, 368, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 373, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 368, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":372
+  /* "pywrapfst.pyx":367
  *                                              id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5521,7 +5545,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":378
+/* "pywrapfst.pyx":373
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5549,7 +5573,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__float__", 0);
 
-  /* "pywrapfst.pyx":379
+  /* "pywrapfst.pyx":374
  * 
  *   def __float__(self):
  *     return float(self.to_string())             # <<<<<<<<<<<<<<
@@ -5559,18 +5583,18 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-    __PYX_ERR(0, 379, __pyx_L1_error)
+    __PYX_ERR(0, 374, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 379, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 374, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 379, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 374, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":378
+  /* "pywrapfst.pyx":373
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5590,7 +5614,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":381
+/* "pywrapfst.pyx":376
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5626,11 +5650,11 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 381, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 376, __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, 381, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 376, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -5643,7 +5667,7 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 381, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 376, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Weight.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -5663,7 +5687,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   std::string __pyx_t_2;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":382
+  /* "pywrapfst.pyx":377
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5672,20 +5696,20 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 382, __pyx_L1_error)
+    __PYX_ERR(0, 377, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 382, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 377, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":383
+  /* "pywrapfst.pyx":378
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weighttostring(weight)))             # <<<<<<<<<<<<<<
  *     self._check_weight()
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 383, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 378, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":382
+  /* "pywrapfst.pyx":377
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5694,7 +5718,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   __pyx_v_self->_weight.reset(new fst::script::WeightClass(__pyx_t_1, __pyx_t_2));
 
-  /* "pywrapfst.pyx":384
+  /* "pywrapfst.pyx":379
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weighttostring(weight)))
  *     self._check_weight()             # <<<<<<<<<<<<<<
@@ -5703,11 +5727,11 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_weight");
-    __PYX_ERR(0, 384, __pyx_L1_error)
+    __PYX_ERR(0, 379, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 384, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 379, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":381
+  /* "pywrapfst.pyx":376
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5726,12 +5750,12 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":386
+/* "pywrapfst.pyx":381
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
  *     if self.type() == b"none":
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  */
 
 static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self) {
@@ -5739,193 +5763,92 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("_check_weight", 0);
 
-  /* "pywrapfst.pyx":387
+  /* "pywrapfst.pyx":382
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  *     if self.to_string() == b"BadNumber":
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "type");
-    __PYX_ERR(0, 387, __pyx_L1_error)
+    __PYX_ERR(0, 382, __pyx_L1_error)
   }
   __pyx_t_1 = ((((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0) == ((char *)"none")) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":388
+    /* "pywrapfst.pyx":383
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":
- *       raise FstUnknownWeightTypeError(self.type())             # <<<<<<<<<<<<<<
+ *       raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *     if self.to_string() == b"BadNumber":
- *       raise FstBadWeightError(self.to_string())
+ *       raise FstBadWeightError("Invalid weight")
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstUnknownWeightTypeError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 388, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 383, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 383, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "type");
-      __PYX_ERR(0, 388, __pyx_L1_error)
-    }
-    __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 388, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
-      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
-      if (likely(__pyx_t_5)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-        __Pyx_INCREF(__pyx_t_5);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_3, function);
-      }
-    }
-    if (!__pyx_t_5) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 388, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_GOTREF(__pyx_t_2);
-    } else {
-      #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_3)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 388, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      } else
-      #endif
-      #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 388, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      } else
-      #endif
-      {
-        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 388, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_6);
-        __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
-        __Pyx_GIVEREF(__pyx_t_4);
-        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
-        __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 388, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      }
-    }
-    __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, 388, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __PYX_ERR(0, 383, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":387
+    /* "pywrapfst.pyx":382
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  *     if self.to_string() == b"BadNumber":
  */
   }
 
-  /* "pywrapfst.pyx":389
+  /* "pywrapfst.pyx":384
  *     if self.type() == b"none":
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  *     if self.to_string() == b"BadNumber":             # <<<<<<<<<<<<<<
- *       raise FstBadWeightError(self.to_string())
+ *       raise FstBadWeightError("Invalid weight")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-    __PYX_ERR(0, 389, __pyx_L1_error)
+    __PYX_ERR(0, 384, __pyx_L1_error)
   }
   __pyx_t_1 = ((((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0) == ((char *)"BadNumber")) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":390
- *       raise FstUnknownWeightTypeError(self.type())
+    /* "pywrapfst.pyx":385
+ *       raise FstArgError("Weight type not found")
  *     if self.to_string() == b"BadNumber":
- *       raise FstBadWeightError(self.to_string())             # <<<<<<<<<<<<<<
+ *       raise FstBadWeightError("Invalid weight")             # <<<<<<<<<<<<<<
  * 
  *   cpdef Weight copy(self):
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 390, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 385, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-      __PYX_ERR(0, 390, __pyx_L1_error)
-    }
-    __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 390, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
-      if (likely(__pyx_t_4)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-        __Pyx_INCREF(__pyx_t_4);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_3, function);
-      }
-    }
-    if (!__pyx_t_4) {
-      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __Pyx_GOTREF(__pyx_t_2);
-    } else {
-      #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_3)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      } else
-      #endif
-      #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      } else
-      #endif
-      {
-        __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 390, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_5);
-        __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
-        __Pyx_GIVEREF(__pyx_t_6);
-        PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_6);
-        __pyx_t_6 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      }
-    }
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __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, 390, __pyx_L1_error)
+    __PYX_ERR(0, 385, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":389
+    /* "pywrapfst.pyx":384
  *     if self.type() == b"none":
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  *     if self.to_string() == b"BadNumber":             # <<<<<<<<<<<<<<
- *       raise FstBadWeightError(self.to_string())
+ *       raise FstBadWeightError("Invalid weight")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":386
+  /* "pywrapfst.pyx":381
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
  *     if self.type() == b"none":
- *       raise FstUnknownWeightTypeError(self.type())
+ *       raise FstArgError("Weight type not found")
  */
 
   /* function exit code */
@@ -5933,16 +5856,13 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst.Weight._check_weight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":392
- *       raise FstBadWeightError(self.to_string())
+/* "pywrapfst.pyx":387
+ *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -5963,7 +5883,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 392, __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, 387, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_6Weight_9copy)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -5979,14 +5899,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 392, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 387, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 392, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 387, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 392, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 387, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -5995,20 +5915,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":398
+  /* "pywrapfst.pyx":393
  *     Returns a copy of the Weight.
  *     """
  *     cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     result._weight.reset(new
  *         fst.WeightClass(<fst.WeightClass> deref(self._weight)))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 398, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 398, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 393, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":399
+  /* "pywrapfst.pyx":394
  *     """
  *     cdef Weight result = Weight.__new__(Weight)
  *     result._weight.reset(new             # <<<<<<<<<<<<<<
@@ -6017,10 +5937,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 399, __pyx_L1_error)
+    __PYX_ERR(0, 394, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":400
+  /* "pywrapfst.pyx":395
  *     cdef Weight result = Weight.__new__(Weight)
  *     result._weight.reset(new
  *         fst.WeightClass(<fst.WeightClass> deref(self._weight)))             # <<<<<<<<<<<<<<
@@ -6029,10 +5949,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 400, __pyx_L1_error)
+    __PYX_ERR(0, 395, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":399
+  /* "pywrapfst.pyx":394
  *     """
  *     cdef Weight result = Weight.__new__(Weight)
  *     result._weight.reset(new             # <<<<<<<<<<<<<<
@@ -6041,7 +5961,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(((fst::script::WeightClass)(*__pyx_v_self->_weight))));
 
-  /* "pywrapfst.pyx":401
+  /* "pywrapfst.pyx":396
  *     result._weight.reset(new
  *         fst.WeightClass(<fst.WeightClass> deref(self._weight)))
  *     return result             # <<<<<<<<<<<<<<
@@ -6053,8 +5973,8 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":392
- *       raise FstBadWeightError(self.to_string())
+  /* "pywrapfst.pyx":387
+ *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -6096,7 +6016,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 392, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 387, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6113,7 +6033,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":407
+/* "pywrapfst.pyx":402
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6123,7 +6043,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_11Zero(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type); /*proto*/
-static char __pyx_doc_9pywrapfst_6Weight_10Zero[] = "\n    Weight.Zero(weight_type)\n    ";
+static char __pyx_doc_9pywrapfst_6Weight_10Zero[] = "\n    Weight.Zero(weight_type)\n\n    Constructs semiring zero.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_6Weight_11Zero(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -6141,21 +6061,21 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("Zero", 0);
 
-  /* "pywrapfst.pyx":411
- *     Weight.Zero(weight_type)
+  /* "pywrapfst.pyx":408
+ *     Constructs semiring zero.
  *     """
  *     return _Weight_Zero(weight_type)             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_Zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 411, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_Zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 408, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":407
+  /* "pywrapfst.pyx":402
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6174,7 +6094,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":414
+/* "pywrapfst.pyx":411
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6184,7 +6104,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_13One(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type); /*proto*/
-static char __pyx_doc_9pywrapfst_6Weight_12One[] = "\n    Weight.One(weight_type)\n    ";
+static char __pyx_doc_9pywrapfst_6Weight_12One[] = "\n    Weight.One(weight_type)\n\n    Constructs semiring One.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_6Weight_13One(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -6202,21 +6122,21 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("One", 0);
 
-  /* "pywrapfst.pyx":418
- *     Weight.One(weight_type)
+  /* "pywrapfst.pyx":417
+ *     Constructs semiring One.
  *     """
  *     return _Weight_One(weight_type)             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_One(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 418, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_One(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 417, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":414
+  /* "pywrapfst.pyx":411
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6235,7 +6155,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":421
+/* "pywrapfst.pyx":420
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6245,7 +6165,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_15NoWeight(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type); /*proto*/
-static char __pyx_doc_9pywrapfst_6Weight_14NoWeight[] = "\n    Weight.NoWeight(weight_type)\n    ";
+static char __pyx_doc_9pywrapfst_6Weight_14NoWeight[] = "\n    Weight.NoWeight(weight_type)\n\n    Constructs a non-member weight in the semiring.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_6Weight_15NoWeight(PyObject *__pyx_v_cls, PyObject *__pyx_v_weight_type) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -6263,21 +6183,21 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("NoWeight", 0);
 
-  /* "pywrapfst.pyx":425
- *     Weight.NoWeight(weight_type)
+  /* "pywrapfst.pyx":426
+ *     Constructs a non-member weight in the semiring.
  *     """
  *     return _Weight_NoWeight(weight_type)             # <<<<<<<<<<<<<<
  * 
  *   def __richcmp__(Weight x, Weight y, int op):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_NoWeight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 425, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Weight_NoWeight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 426, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":421
+  /* "pywrapfst.pyx":420
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6296,7 +6216,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":427
+/* "pywrapfst.pyx":428
  *     return _Weight_NoWeight(weight_type)
  * 
  *   def __richcmp__(Weight x, Weight y, int op):             # <<<<<<<<<<<<<<
@@ -6310,8 +6230,8 @@ static PyObject *__pyx_pw_9pywrapfst_6Weight_17__richcmp__(PyObject *__pyx_v_x,
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_9pywrapfst_Weight, 1, "x", 0))) __PYX_ERR(0, 427, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_9pywrapfst_Weight, 1, "y", 0))) __PYX_ERR(0, 427, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_x), __pyx_ptype_9pywrapfst_Weight, 1, "x", 0))) __PYX_ERR(0, 428, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_9pywrapfst_Weight, 1, "y", 0))) __PYX_ERR(0, 428, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6Weight_16__richcmp__(((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_x), ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_y), ((int)__pyx_v_op));
 
   /* function exit code */
@@ -6334,7 +6254,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__richcmp__", 0);
 
-  /* "pywrapfst.pyx":429
+  /* "pywrapfst.pyx":430
  *   def __richcmp__(Weight x, Weight y, int op):
  *     # This is useful for unit tests.
  *     if op == 2:  # `==`             # <<<<<<<<<<<<<<
@@ -6344,7 +6264,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
   switch (__pyx_v_op) {
     case 2:
 
-    /* "pywrapfst.pyx":430
+    /* "pywrapfst.pyx":431
  *     # This is useful for unit tests.
  *     if op == 2:  # `==`
  *       return (x.type() == y.type() and x.to_string() == y.to_string())             # <<<<<<<<<<<<<<
@@ -6354,16 +6274,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
     __Pyx_XDECREF(__pyx_r);
     if (unlikely(((PyObject *)__pyx_v_x) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "type");
-      __PYX_ERR(0, 430, __pyx_L1_error)
+      __PYX_ERR(0, 431, __pyx_L1_error)
     }
     if (unlikely(((PyObject *)__pyx_v_y) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "type");
-      __PYX_ERR(0, 430, __pyx_L1_error)
+      __PYX_ERR(0, 431, __pyx_L1_error)
     }
     __pyx_t_2 = (((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_x->__pyx_vtab)->type(__pyx_v_x, 0) == ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_y->__pyx_vtab)->type(__pyx_v_y, 0));
     if (__pyx_t_2) {
     } else {
-      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 430, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 431, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __pyx_t_1 = __pyx_t_3;
       __pyx_t_3 = 0;
@@ -6371,14 +6291,14 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
     }
     if (unlikely(((PyObject *)__pyx_v_x) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-      __PYX_ERR(0, 430, __pyx_L1_error)
+      __PYX_ERR(0, 431, __pyx_L1_error)
     }
     if (unlikely(((PyObject *)__pyx_v_y) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "to_string");
-      __PYX_ERR(0, 430, __pyx_L1_error)
+      __PYX_ERR(0, 431, __pyx_L1_error)
     }
     __pyx_t_2 = (((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_x->__pyx_vtab)->to_string(__pyx_v_x, 0) == ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_y->__pyx_vtab)->to_string(__pyx_v_y, 0));
-    __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 430, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 431, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_1 = __pyx_t_3;
     __pyx_t_3 = 0;
@@ -6387,7 +6307,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
     __pyx_t_1 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":429
+    /* "pywrapfst.pyx":430
  *   def __richcmp__(Weight x, Weight y, int op):
  *     # This is useful for unit tests.
  *     if op == 2:  # `==`             # <<<<<<<<<<<<<<
@@ -6396,7 +6316,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
  */
     break;
 
-    /* "pywrapfst.pyx":431
+    /* "pywrapfst.pyx":432
  *     if op == 2:  # `==`
  *       return (x.type() == y.type() and x.to_string() == y.to_string())
  *     elif op == 3:  # `!=`             # <<<<<<<<<<<<<<
@@ -6405,7 +6325,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
  */
     case 3:
 
-    /* "pywrapfst.pyx":432
+    /* "pywrapfst.pyx":433
  *       return (x.type() == y.type() and x.to_string() == y.to_string())
  *     elif op == 3:  # `!=`
  *       return not (x == y)             # <<<<<<<<<<<<<<
@@ -6413,16 +6333,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
  *       raise NotImplementedError("Invalid operator {!r}".format(op))
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_x), ((PyObject *)__pyx_v_y), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error)
-    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 432, __pyx_L1_error)
+    __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_x), ((PyObject *)__pyx_v_y), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 433, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 433, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 433, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __pyx_r = __pyx_t_1;
     __pyx_t_1 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":431
+    /* "pywrapfst.pyx":432
  *     if op == 2:  # `==`
  *       return (x.type() == y.type() and x.to_string() == y.to_string())
  *     elif op == 3:  # `!=`             # <<<<<<<<<<<<<<
@@ -6432,16 +6352,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
     break;
     default:
 
-    /* "pywrapfst.pyx":434
+    /* "pywrapfst.pyx":435
  *       return not (x == y)
  *     else:
  *       raise NotImplementedError("Invalid operator {!r}".format(op))             # <<<<<<<<<<<<<<
  * 
  *   cpdef string to_string(self):
  */
-    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Invalid_operator_r, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 434, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Invalid_operator_r, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 435, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_op); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 434, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_op); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 435, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
@@ -6454,14 +6374,14 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -6470,40 +6390,40 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_4};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 434, __pyx_L1_error)
+        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 435, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       }
     }
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 434, __pyx_L1_error)
+    __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 435, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_1);
     PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
     __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __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, 434, __pyx_L1_error)
+    __PYX_ERR(0, 435, __pyx_L1_error)
     break;
   }
 
-  /* "pywrapfst.pyx":427
+  /* "pywrapfst.pyx":428
  *     return _Weight_NoWeight(weight_type)
  * 
  *   def __richcmp__(Weight x, Weight y, int op):             # <<<<<<<<<<<<<<
@@ -6526,7 +6446,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__richcmp__(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":436
+/* "pywrapfst.pyx":437
  *       raise NotImplementedError("Invalid operator {!r}".format(op))
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6548,7 +6468,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 436, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 437, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_6Weight_19to_string)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -6563,14 +6483,14 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 436, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 436, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __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, 436, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 437, __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;
@@ -6579,7 +6499,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":437
+  /* "pywrapfst.pyx":438
  * 
  *   cpdef string to_string(self):
  *     return self._weight.get().ToString()             # <<<<<<<<<<<<<<
@@ -6588,12 +6508,12 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 437, __pyx_L1_error)
+    __PYX_ERR(0, 438, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->ToString();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":436
+  /* "pywrapfst.pyx":437
  *       raise NotImplementedError("Invalid operator {!r}".format(op))
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6632,7 +6552,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18to_string(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 436, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 437, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6649,11 +6569,11 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18to_string(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":439
+/* "pywrapfst.pyx":440
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
- *     return self._weight.get().Type()
+ *     """type(self)
  * 
  */
 
@@ -6671,7 +6591,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 439, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 440, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_6Weight_21type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -6686,14 +6606,14 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 439, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 440, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 439, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 440, __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, 439, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 440, __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;
@@ -6702,25 +6622,25 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":440
- * 
- *   cpdef string type(self):
+  /* "pywrapfst.pyx":445
+ *     Returns a string indicating the weight type.
+ *     """
  *     return self._weight.get().Type()             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 440, __pyx_L1_error)
+    __PYX_ERR(0, 445, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Type();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":439
+  /* "pywrapfst.pyx":440
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
- *     return self._weight.get().Type()
+ *     """type(self)
  * 
  */
 
@@ -6738,6 +6658,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_21type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_6Weight_20type[] = "type(self)\n\n    Returns a string indicating the weight type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_6Weight_21type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -6755,7 +6676,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20type(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 439, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 440, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6772,7 +6693,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20type(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":443
+/* "pywrapfst.pyx":448
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6787,20 +6708,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_plus", 0);
 
-  /* "pywrapfst.pyx":444
+  /* "pywrapfst.pyx":449
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                     deref(rhs._weight))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 444, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 444, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 449, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":450
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -6809,14 +6730,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 445, __pyx_L1_error)
+    __PYX_ERR(0, 450, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 445, __pyx_L1_error)
+    __PYX_ERR(0, 450, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":446
+  /* "pywrapfst.pyx":451
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                     deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -6825,10 +6746,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 446, __pyx_L1_error)
+    __PYX_ERR(0, 451, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":450
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -6837,7 +6758,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Plus((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":447
+  /* "pywrapfst.pyx":452
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                     deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -6849,7 +6770,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":443
+  /* "pywrapfst.pyx":448
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6869,7 +6790,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":450
+/* "pywrapfst.pyx":455
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6879,7 +6800,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_plus[] = "\n  plus(lhs, rhs)\n\n  Computes the sum of two Weights in the same semiring.\n\n  This function computes lhs \\oplus rhs, raising an exception if lhs and rhs\n  are not in the same semiring.\n\n  Args:\n     lhs: left-hand side Weight.\n     rhs: right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstBadWeightError: invalid weight.\n    FstUnknownWeightTypeError: weights are null or not in the same semiring.\n  ";
+static char __pyx_doc_9pywrapfst_plus[] = "\n  plus(lhs, rhs)\n\n  Computes the sum of two Weights in the same semiring.\n\n  This function computes lhs \\oplus rhs, raising an exception if lhs and rhs\n  are not in the same semiring.\n\n  Args:\n     lhs: Left-hand side Weight.\n     rhs: Right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstArgError: Weight type not found (or not in same semiring).\n    FstBadWeightError: invalid weight.\n  ";
 static PyMethodDef __pyx_mdef_9pywrapfst_1plus = {"plus", (PyCFunction)__pyx_pw_9pywrapfst_1plus, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_plus};
 static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
@@ -6907,11 +6828,11 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 450, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 455, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 450, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 455, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -6924,14 +6845,14 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 450, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 455, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.plus", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 450, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 450, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 455, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 455, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_plus(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -6950,19 +6871,19 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("plus", 0);
 
-  /* "pywrapfst.pyx":470
- *     FstUnknownWeightTypeError: weights are null or not in the same semiring.
+  /* "pywrapfst.pyx":475
+ *     FstBadWeightError: invalid weight.
  *   """
  *   cdef Weight result = _plus(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 475, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":471
+  /* "pywrapfst.pyx":476
  *   """
  *   cdef Weight result = _plus(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -6971,11 +6892,11 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_weight");
-    __PYX_ERR(0, 471, __pyx_L1_error)
+    __PYX_ERR(0, 476, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 471, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 476, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":472
+  /* "pywrapfst.pyx":477
  *   cdef Weight result = _plus(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -6987,7 +6908,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":455
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7007,7 +6928,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":475
+/* "pywrapfst.pyx":480
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7022,20 +6943,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_times", 0);
 
-  /* "pywrapfst.pyx":476
+  /* "pywrapfst.pyx":481
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                      deref(rhs._weight))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 476, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 476, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 481, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":482
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7044,14 +6965,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 477, __pyx_L1_error)
+    __PYX_ERR(0, 482, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 477, __pyx_L1_error)
+    __PYX_ERR(0, 482, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":478
+  /* "pywrapfst.pyx":483
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                      deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7060,10 +6981,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 478, __pyx_L1_error)
+    __PYX_ERR(0, 483, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":482
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7072,7 +6993,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Times((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":479
+  /* "pywrapfst.pyx":484
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                      deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -7084,7 +7005,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":475
+  /* "pywrapfst.pyx":480
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7104,7 +7025,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":482
+/* "pywrapfst.pyx":487
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7114,7 +7035,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_2times[] = "\n  times(lhs, rhs)\n\n  Computes the product of two Weights in the same semiring.\n\n  This function computes lhs \\otimes rhs, raising an exception if lhs and rhs\n  are not in the same semiring.\n\n  Args:\n     lhs: left-hand side Weight.\n     rhs: right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstBadWeightError: invalid weight.\n    FstUnknownWeightTypeError: weights are null or not in the same semiring.\n  ";
+static char __pyx_doc_9pywrapfst_2times[] = "\n  times(lhs, rhs)\n\n  Computes the product of two Weights in the same semiring.\n\n  This function computes lhs \\otimes rhs, raising an exception if lhs and rhs\n  are not in the same semiring.\n\n  Args:\n     lhs: Left-hand side Weight.\n     rhs: Right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstArgError: Weight type not found (or not in same semiring).\n    FstBadWeightError: Invalid weight.\n  ";
 static PyMethodDef __pyx_mdef_9pywrapfst_3times = {"times", (PyCFunction)__pyx_pw_9pywrapfst_3times, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_2times};
 static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
@@ -7142,11 +7063,11 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 482, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 487, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 482, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 487, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7159,14 +7080,14 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 482, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 487, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.times", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 482, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 482, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 487, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 487, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_2times(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7185,19 +7106,19 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("times", 0);
 
-  /* "pywrapfst.pyx":502
- *     FstUnknownWeightTypeError: weights are null or not in the same semiring.
+  /* "pywrapfst.pyx":507
+ *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _times(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":503
+  /* "pywrapfst.pyx":508
  *   """
  *   cdef Weight result = _times(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7206,11 +7127,11 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_weight");
-    __PYX_ERR(0, 503, __pyx_L1_error)
+    __PYX_ERR(0, 508, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 503, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 508, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":504
+  /* "pywrapfst.pyx":509
  *   cdef Weight result = _times(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7222,7 +7143,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":487
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7242,7 +7163,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":507
+/* "pywrapfst.pyx":512
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7257,20 +7178,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_divide", 0);
 
-  /* "pywrapfst.pyx":508
+  /* "pywrapfst.pyx":513
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                       deref(rhs._weight))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 508, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 513, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 508, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 513, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":514
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7279,14 +7200,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 514, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 514, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":510
+  /* "pywrapfst.pyx":515
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                       deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7295,10 +7216,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 510, __pyx_L1_error)
+    __PYX_ERR(0, 515, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":514
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7307,7 +7228,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Divide((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":511
+  /* "pywrapfst.pyx":516
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                       deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -7319,7 +7240,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":507
+  /* "pywrapfst.pyx":512
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7339,7 +7260,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":514
+/* "pywrapfst.pyx":519
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7349,7 +7270,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4divide[] = "\n  divide(lhs, rhs)\n\n  Computes the quotient of two Weights in the same semiring.\n\n  This function computes lhs \\oslash rhs, raising an exception if lhs and rhs\n  are not in the same semiring. As there is no way to specify whether to use\n  left vs. right division, this assumes a commutative semiring in which these\n  are equivalent operations.\n\n  Args:\n     lhs: left-hand side Weight.\n     rhs: right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstBadWeightError: invalid weight.\n    FstUnknownWeightTypeError: weights are null or not in the same semiring.\n  ";
+static char __pyx_doc_9pywrapfst_4divide[] = "\n  divide(lhs, rhs)\n\n  Computes the quotient of two Weights in the same semiring.\n\n  This function computes lhs \\oslash rhs, raising an exception if lhs and rhs\n  are not in the same semiring. As there is no way to specify whether to use\n  left vs. right division, this assumes a commutative semiring in which these\n  are equivalent operations.\n\n  Args:\n     lhs: Left-hand side Weight.\n     rhs: Right-hand side Weight.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstArgError: Weight type not found (or not in same semiring).\n    FstBadWeightError: Invalid weight.\n  ";
 static PyMethodDef __pyx_mdef_9pywrapfst_5divide = {"divide", (PyCFunction)__pyx_pw_9pywrapfst_5divide, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4divide};
 static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
@@ -7377,11 +7298,11 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 514, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 519, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 514, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 519, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7394,14 +7315,14 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 514, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 519, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.divide", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 519, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 519, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4divide(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7420,19 +7341,19 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("divide", 0);
 
-  /* "pywrapfst.pyx":536
- *     FstUnknownWeightTypeError: weights are null or not in the same semiring.
+  /* "pywrapfst.pyx":541
+ *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _divide(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 536, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 541, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":537
+  /* "pywrapfst.pyx":542
  *   """
  *   cdef Weight result = _divide(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7441,11 +7362,11 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_weight");
-    __PYX_ERR(0, 537, __pyx_L1_error)
+    __PYX_ERR(0, 542, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 537, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 542, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":538
+  /* "pywrapfst.pyx":543
  *   cdef Weight result = _divide(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7457,7 +7378,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":519
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7477,7 +7398,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":541
+/* "pywrapfst.pyx":546
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7492,20 +7413,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_power", 0);
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":547
  * 
  * cdef Weight _power(Weight w, size_t n):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  *   return result
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 547, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 542, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 547, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":543
+  /* "pywrapfst.pyx":548
  * cdef Weight _power(Weight w, size_t n):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))             # <<<<<<<<<<<<<<
@@ -7514,15 +7435,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 543, __pyx_L1_error)
+    __PYX_ERR(0, 548, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_w) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 543, __pyx_L1_error)
+    __PYX_ERR(0, 548, __pyx_L1_error)
   }
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Power((*__pyx_v_w->_weight), __pyx_v_n)));
 
-  /* "pywrapfst.pyx":544
+  /* "pywrapfst.pyx":549
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  *   return result             # <<<<<<<<<<<<<<
@@ -7534,7 +7455,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":541
+  /* "pywrapfst.pyx":546
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7554,17 +7475,17 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":547
+/* "pywrapfst.pyx":552
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
- *   times(lhs, rhs)
+ *   power(lhs, rhs)
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_6power[] = "\n  times(lhs, rhs)\n\n  Computes the iterated product of a weight.\n\n  Args:\n     w: The weight.\n     n: The power.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstBadWeightError: invalid weight.\n    FstUnknownWeightTypeError: weights are null or not in the same semiring.\n  ";
+static char __pyx_doc_9pywrapfst_6power[] = "\n  power(lhs, rhs)\n\n  Computes the iterated product of a weight.\n\n  Args:\n     w: The weight.\n     n: The power.\n\n  Returns:\n    A Weight object.\n\n  Raises:\n    FstArgError: Weight type not found (or not in same semiring).\n    FstBadWeightError: Invalid weight.\n  ";
 static PyMethodDef __pyx_mdef_9pywrapfst_7power = {"power", (PyCFunction)__pyx_pw_9pywrapfst_7power, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_6power};
 static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_w = 0;
@@ -7592,11 +7513,11 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 547, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 552, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 547, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 552, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7605,17 +7526,17 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_w = ((struct __pyx_obj_9pywrapfst_Weight *)values[0]);
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 547, __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, 552, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 547, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 552, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.power", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 547, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 552, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6power(__pyx_self, __pyx_v_w, __pyx_v_n);
 
   /* function exit code */
@@ -7634,19 +7555,19 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("power", 0);
 
-  /* "pywrapfst.pyx":564
- *     FstUnknownWeightTypeError: weights are null or not in the same semiring.
+  /* "pywrapfst.pyx":569
+ *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _power(w, n)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 569, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":565
+  /* "pywrapfst.pyx":570
  *   """
  *   cdef Weight result = _power(w, n)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7655,11 +7576,11 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_weight");
-    __PYX_ERR(0, 565, __pyx_L1_error)
+    __PYX_ERR(0, 570, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 565, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 570, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":566
+  /* "pywrapfst.pyx":571
  *   cdef Weight result = _power(w, n)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7671,12 +7592,12 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":552
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
- *   times(lhs, rhs)
+ *   power(lhs, rhs)
  */
 
   /* function exit code */
@@ -7691,7 +7612,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":569
+/* "pywrapfst.pyx":574
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7713,7 +7634,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_Zero", 0);
 
-  /* "pywrapfst.pyx":587
+  /* "pywrapfst.pyx":592
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7724,7 +7645,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":588
+    /* "pywrapfst.pyx":593
  *   cdef fst.WeightClass result
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)             # <<<<<<<<<<<<<<
@@ -7733,7 +7654,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  */
     __pyx_v_result = fst::script::WeightClass::Zero(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":587
+    /* "pywrapfst.pyx":592
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7743,7 +7664,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":589
+  /* "pywrapfst.pyx":594
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7754,7 +7675,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":590
+    /* "pywrapfst.pyx":595
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -7763,11 +7684,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-      __PYX_ERR(0, 590, __pyx_L1_error)
+      __PYX_ERR(0, 595, __pyx_L1_error)
     }
     __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":589
+    /* "pywrapfst.pyx":594
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7777,7 +7698,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":592
+  /* "pywrapfst.pyx":597
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))             # <<<<<<<<<<<<<<
@@ -7785,10 +7706,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  *       raise FstBadWeightError(weighttostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 592, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 597, __pyx_L1_error)
     __pyx_v_result = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":593
+    /* "pywrapfst.pyx":598
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":             # <<<<<<<<<<<<<<
@@ -7798,17 +7719,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     __pyx_t_1 = ((__pyx_v_result.ToString() == ((char *)"BadNumber")) != 0);
     if (__pyx_t_1) {
 
-      /* "pywrapfst.pyx":594
+      /* "pywrapfst.pyx":599
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":
  *       raise FstBadWeightError(weighttostring(weight))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 594, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 599, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 594, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 599, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 599, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -7821,14 +7742,14 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
         }
       }
       if (!__pyx_t_7) {
-        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 599, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-          __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 599, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -7837,20 +7758,20 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-          __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 599, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 594, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 599, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
           __Pyx_GIVEREF(__pyx_t_6);
           PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
           __pyx_t_6 = 0;
-          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 599, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -7858,9 +7779,9 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
       __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, 594, __pyx_L1_error)
+      __PYX_ERR(0, 599, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":593
+      /* "pywrapfst.pyx":598
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":             # <<<<<<<<<<<<<<
@@ -7871,7 +7792,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":595
+  /* "pywrapfst.pyx":600
  *     if result.ToString() == b"BadNumber":
  *       raise FstBadWeightError(weighttostring(weight))
  *   return result             # <<<<<<<<<<<<<<
@@ -7881,7 +7802,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":569
+  /* "pywrapfst.pyx":574
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7902,7 +7823,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":598
+/* "pywrapfst.pyx":603
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7924,7 +7845,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_One", 0);
 
-  /* "pywrapfst.pyx":616
+  /* "pywrapfst.pyx":621
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7935,7 +7856,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":617
+    /* "pywrapfst.pyx":622
  *   cdef fst.WeightClass result
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)             # <<<<<<<<<<<<<<
@@ -7944,7 +7865,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  */
     __pyx_v_result = fst::script::WeightClass::One(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":616
+    /* "pywrapfst.pyx":621
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7954,7 +7875,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":618
+  /* "pywrapfst.pyx":623
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7965,7 +7886,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":619
+    /* "pywrapfst.pyx":624
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -7974,11 +7895,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-      __PYX_ERR(0, 619, __pyx_L1_error)
+      __PYX_ERR(0, 624, __pyx_L1_error)
     }
     __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":618
+    /* "pywrapfst.pyx":623
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7988,7 +7909,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":621
+  /* "pywrapfst.pyx":626
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))             # <<<<<<<<<<<<<<
@@ -7996,10 +7917,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  *       raise FstBadWeightError(weighttostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 621, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 626, __pyx_L1_error)
     __pyx_v_result = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":622
+    /* "pywrapfst.pyx":627
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":             # <<<<<<<<<<<<<<
@@ -8009,17 +7930,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     __pyx_t_1 = ((__pyx_v_result.ToString() == ((char *)"BadNumber")) != 0);
     if (__pyx_t_1) {
 
-      /* "pywrapfst.pyx":623
+      /* "pywrapfst.pyx":628
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":
  *       raise FstBadWeightError(weighttostring(weight))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 623, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 628, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 623, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 623, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weighttostring(__pyx_v_weight, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 628, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 628, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -8032,14 +7953,14 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
         }
       }
       if (!__pyx_t_7) {
-        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 628, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-          __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 628, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -8048,20 +7969,20 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-          __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 628, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 623, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 628, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
           __Pyx_GIVEREF(__pyx_t_6);
           PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
           __pyx_t_6 = 0;
-          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 628, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -8069,9 +7990,9 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
       __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, 623, __pyx_L1_error)
+      __PYX_ERR(0, 628, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":622
+      /* "pywrapfst.pyx":627
  *   else:
  *     result = fst.WeightClass(weight_type, weighttostring(weight))
  *     if result.ToString() == b"BadNumber":             # <<<<<<<<<<<<<<
@@ -8082,7 +8003,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":624
+  /* "pywrapfst.pyx":629
  *     if result.ToString() == b"BadNumber":
  *       raise FstBadWeightError(weighttostring(weight))
  *   return result             # <<<<<<<<<<<<<<
@@ -8092,7 +8013,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":598
+  /* "pywrapfst.pyx":603
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8113,7 +8034,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":627
+/* "pywrapfst.pyx":632
  * 
  * 
  * cdef Weight _Weight_Zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8129,24 +8050,22 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
   std::string __pyx_t_2;
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("_Weight_Zero", 0);
 
-  /* "pywrapfst.pyx":628
+  /* "pywrapfst.pyx":633
  * 
  * cdef Weight _Weight_Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 633, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 628, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 633, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":629
+  /* "pywrapfst.pyx":634
  * cdef Weight _Weight_Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
@@ -8155,19 +8074,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 629, __pyx_L1_error)
+    __PYX_ERR(0, 634, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":630
+  /* "pywrapfst.pyx":635
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 630, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 635, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":629
+  /* "pywrapfst.pyx":634
  * cdef Weight _Weight_Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
@@ -8176,88 +8095,48 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::Zero(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":631
+  /* "pywrapfst.pyx":636
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 631, __pyx_L1_error)
+    __PYX_ERR(0, 636, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char *)"none")) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":632
+    /* "pywrapfst.pyx":637
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)             # <<<<<<<<<<<<<<
+ *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstUnknownWeightTypeError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 632, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 637, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 637, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __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);
-      }
-    }
-    if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_1);
-    } else {
-      #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_weight_type};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_1);
-      } else
-      #endif
-      #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_weight_type};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_1);
-      } else
-      #endif
-      {
-        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 632, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_6);
-        __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
-        __Pyx_INCREF(__pyx_v_weight_type);
-        __Pyx_GIVEREF(__pyx_v_weight_type);
-        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_weight_type);
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      }
-    }
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 632, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __PYX_ERR(0, 637, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":631
+    /* "pywrapfst.pyx":636
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result
  */
   }
 
-  /* "pywrapfst.pyx":633
+  /* "pywrapfst.pyx":638
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -8267,7 +8146,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":627
+  /* "pywrapfst.pyx":632
  * 
  * 
  * cdef Weight _Weight_Zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8279,8 +8158,6 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst._Weight_Zero", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -8290,7 +8167,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_Zero(PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":636
+/* "pywrapfst.pyx":641
  * 
  * 
  * cdef Weight _Weight_One(weight_type):             # <<<<<<<<<<<<<<
@@ -8306,24 +8183,22 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
   std::string __pyx_t_2;
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("_Weight_One", 0);
 
-  /* "pywrapfst.pyx":637
+  /* "pywrapfst.pyx":642
  * 
  * cdef Weight _Weight_One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 637, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 642, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 637, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 642, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":638
+  /* "pywrapfst.pyx":643
  * cdef Weight _Weight_One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8332,19 +8207,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 638, __pyx_L1_error)
+    __PYX_ERR(0, 643, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":639
+  /* "pywrapfst.pyx":644
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 639, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 644, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":638
+  /* "pywrapfst.pyx":643
  * cdef Weight _Weight_One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8353,88 +8228,48 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::One(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":640
+  /* "pywrapfst.pyx":645
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 640, __pyx_L1_error)
+    __PYX_ERR(0, 645, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char *)"none")) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":641
+    /* "pywrapfst.pyx":646
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)             # <<<<<<<<<<<<<<
+ *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstUnknownWeightTypeError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 641, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 646, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 646, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __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);
-      }
-    }
-    if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_1);
-    } else {
-      #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_weight_type};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_1);
-      } else
-      #endif
-      #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_v_weight_type};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __Pyx_GOTREF(__pyx_t_1);
-      } else
-      #endif
-      {
-        __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 641, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_6);
-        __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
-        __Pyx_INCREF(__pyx_v_weight_type);
-        __Pyx_GIVEREF(__pyx_v_weight_type);
-        PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_weight_type);
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      }
-    }
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 641, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __PYX_ERR(0, 646, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":640
+    /* "pywrapfst.pyx":645
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result
  */
   }
 
-  /* "pywrapfst.pyx":642
+  /* "pywrapfst.pyx":647
  *   if result._weight.get().Type() == b"none":
- *     raise FstUnknownWeightTypeError(weight_type)
+ *     raise FstArgError("Weight type not found")
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -8444,7 +8279,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":636
+  /* "pywrapfst.pyx":641
  * 
  * 
  * cdef Weight _Weight_One(weight_type):             # <<<<<<<<<<<<<<
@@ -8456,8 +8291,6 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst._Weight_One", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -8467,7 +8300,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_One(PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":645
+/* "pywrapfst.pyx":650
  * 
  * 
  * cdef Weight _Weight_NoWeight(weight_type):             # <<<<<<<<<<<<<<
@@ -8483,20 +8316,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_NoWeight(P
   std::string __pyx_t_2;
   __Pyx_RefNannySetupContext("_Weight_NoWeight", 0);
 
-  /* "pywrapfst.pyx":646
+  /* "pywrapfst.pyx":651
  * 
  * cdef Weight _Weight_NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.NoWeight(tostring(weight_type))))
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 646, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 651, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 646, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 651, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":647
+  /* "pywrapfst.pyx":652
  * cdef Weight _Weight_NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8505,19 +8338,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_NoWeight(P
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 647, __pyx_L1_error)
+    __PYX_ERR(0, 652, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":648
+  /* "pywrapfst.pyx":653
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.NoWeight(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 648, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 653, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":647
+  /* "pywrapfst.pyx":652
  * cdef Weight _Weight_NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8526,7 +8359,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_NoWeight(P
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::NoWeight(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":649
+  /* "pywrapfst.pyx":654
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.NoWeight(tostring(weight_type))))
  *   return result             # <<<<<<<<<<<<<<
@@ -8538,7 +8371,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_NoWeight(P
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":645
+  /* "pywrapfst.pyx":650
  * 
  * 
  * cdef Weight _Weight_NoWeight(weight_type):             # <<<<<<<<<<<<<<
@@ -8558,7 +8391,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Weight_NoWeight(P
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":683
+/* "pywrapfst.pyx":688
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8594,28 +8427,28 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":684
+  /* "pywrapfst.pyx":689
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 684, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 689, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":685
+  /* "pywrapfst.pyx":690
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __iter__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 685, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 690, __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, 685, __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, 690, __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, 685, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 690, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -8629,14 +8462,14 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
     }
   }
   if (!__pyx_t_5) {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 685, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 690, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_GOTREF(__pyx_t_3);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 685, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 690, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -8645,20 +8478,20 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 685, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 690, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 685, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 690, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
       __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 685, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 690, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -8675,14 +8508,14 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
     }
   }
   if (!__pyx_t_4) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 689, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -8691,20 +8524,20 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 684, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 689, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -8712,9 +8545,9 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   __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, 684, __pyx_L1_error)
+  __PYX_ERR(0, 689, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":683
+  /* "pywrapfst.pyx":688
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8737,7 +8570,7 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":687
+/* "pywrapfst.pyx":692
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -8765,7 +8598,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":688
+  /* "pywrapfst.pyx":693
  * 
  *   def __iter__(self):
  *     return SymbolTableIterator(self)             # <<<<<<<<<<<<<<
@@ -8773,19 +8606,19 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
  *   cpdef int64 available_key(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 688, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_SymbolTableIterator), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 688, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_SymbolTableIterator), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":687
+  /* "pywrapfst.pyx":692
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -8805,12 +8638,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":690
+/* "pywrapfst.pyx":695
  *     return SymbolTableIterator(self)
  * 
  *   cpdef int64 available_key(self):             # <<<<<<<<<<<<<<
- *     return self._table.AvailableKey()
- * 
+ *     """
+ *     available_key(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_5available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -8827,7 +8660,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 690, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 695, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_5available_key)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -8842,14 +8675,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 690, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 695, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 690, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 695, __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, 690, __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, 695, __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;
@@ -8858,26 +8691,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":691
- * 
- *   cpdef int64 available_key(self):
+  /* "pywrapfst.pyx":701
+ *     Returns an integer indicating the next available key index in the table.
+ *     """
  *     return self._table.AvailableKey()             # <<<<<<<<<<<<<<
  * 
  *   cpdef string checksum(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 691, __pyx_L1_error)
+    __PYX_ERR(0, 701, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_table->AvailableKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":690
+  /* "pywrapfst.pyx":695
  *     return SymbolTableIterator(self)
  * 
  *   cpdef int64 available_key(self):             # <<<<<<<<<<<<<<
- *     return self._table.AvailableKey()
- * 
+ *     """
+ *     available_key(self)
  */
 
   /* function exit code */
@@ -8895,6 +8728,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_5available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_4available_key[] = "\n    available_key(self)\n\n    Returns an integer indicating the next available key index in the table.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_5available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -8912,7 +8746,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4available_key(struct __pyx_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("available_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_12_SymbolTable_available_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 690, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_12_SymbolTable_available_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 695, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -8929,12 +8763,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4available_key(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":693
+/* "pywrapfst.pyx":703
  *     return self._table.AvailableKey()
  * 
  *   cpdef string checksum(self):             # <<<<<<<<<<<<<<
- *     return self._table.CheckSum()
- * 
+ *     """
+ *     checksum(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -8951,7 +8785,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_7checksum)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -8966,14 +8800,14 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 703, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 703, __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, 693, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 703, __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;
@@ -8982,26 +8816,26 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":694
- * 
- *   cpdef string checksum(self):
+  /* "pywrapfst.pyx":709
+ *     Returns a string indicating the label-agnostic MD5 checksum for the table.
+ *     """
  *     return self._table.CheckSum()             # <<<<<<<<<<<<<<
  * 
  *   cpdef SymbolTable copy(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 694, __pyx_L1_error)
+    __PYX_ERR(0, 709, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_table->CheckSum();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":693
+  /* "pywrapfst.pyx":703
  *     return self._table.AvailableKey()
  * 
  *   cpdef string checksum(self):             # <<<<<<<<<<<<<<
- *     return self._table.CheckSum()
- * 
+ *     """
+ *     checksum(self)
  */
 
   /* function exit code */
@@ -9018,6 +8852,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_6checksum[] = "\n    checksum(self)\n\n    Returns a string indicating the label-agnostic MD5 checksum for the table.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -9035,7 +8870,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6checksum(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_checksum(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_checksum(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9052,7 +8887,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6checksum(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":696
+/* "pywrapfst.pyx":711
  *     return self._table.CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9073,7 +8908,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 696, __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, 711, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_9copy)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -9089,14 +8924,14 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 696, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 711, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 696, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 711, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 696, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 711, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9105,7 +8940,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":702
+  /* "pywrapfst.pyx":717
  *     Returns a mutable copy of the SymbolTable.
  *     """
  *     return _init_SymbolTable(self._table.Copy())             # <<<<<<<<<<<<<<
@@ -9115,15 +8950,15 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 702, __pyx_L1_error)
+    __PYX_ERR(0, 717, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_self->_table->Copy())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 702, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_self->_table->Copy())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 717, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":696
+  /* "pywrapfst.pyx":711
  *     return self._table.CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9165,7 +9000,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8copy(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12_SymbolTable_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 696, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12_SymbolTable_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 711, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9182,7 +9017,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8copy(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":704
+/* "pywrapfst.pyx":719
  *     return _init_SymbolTable(self._table.Copy())
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9222,7 +9057,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
   PyObject *__pyx_t_12 = NULL;
   __Pyx_RefNannySetupContext("find", 0);
 
-  /* "pywrapfst.pyx":723
+  /* "pywrapfst.pyx":738
  *       KeyError: Key not found.
  *     """
  *     try:             # <<<<<<<<<<<<<<
@@ -9238,7 +9073,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":724
+      /* "pywrapfst.pyx":739
  *     """
  *     try:
  *       result = self._table.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
@@ -9247,47 +9082,47 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
  */
       if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-        __PYX_ERR(0, 724, __pyx_L3_error)
+        __PYX_ERR(0, 739, __pyx_L3_error)
       }
-      __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 724, __pyx_L3_error)
-      __pyx_t_5 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_table->Find(__pyx_t_4)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 724, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 739, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_table->Find(__pyx_t_4)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 739, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_5);
       __pyx_v_result = __pyx_t_5;
       __pyx_t_5 = 0;
 
-      /* "pywrapfst.pyx":725
+      /* "pywrapfst.pyx":740
  *     try:
  *       result = self._table.FindIndex(tostring(key))
  *       if result == -1:             # <<<<<<<<<<<<<<
  *         raise KeyError(key)
  *     except FstArgError:
  */
-      __pyx_t_5 = __Pyx_PyInt_EqObjC(__pyx_v_result, __pyx_int_neg_1, -1L, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 725, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyInt_EqObjC(__pyx_v_result, __pyx_int_neg_1, -1L, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 740, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 725, __pyx_L3_error)
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 740, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       if (__pyx_t_6) {
 
-        /* "pywrapfst.pyx":726
+        /* "pywrapfst.pyx":741
  *       result = self._table.FindIndex(tostring(key))
  *       if result == -1:
  *         raise KeyError(key)             # <<<<<<<<<<<<<<
  *     except FstArgError:
  *       result = self._table.FindSymbol(key)
  */
-        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 726, __pyx_L3_error)
+        __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 741, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_INCREF(__pyx_v_key);
         __Pyx_GIVEREF(__pyx_v_key);
         PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_key);
-        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 726, __pyx_L3_error)
+        __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 741, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_7);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_Raise(__pyx_t_7, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __PYX_ERR(0, 726, __pyx_L3_error)
+        __PYX_ERR(0, 741, __pyx_L3_error)
 
-        /* "pywrapfst.pyx":725
+        /* "pywrapfst.pyx":740
  *     try:
  *       result = self._table.FindIndex(tostring(key))
  *       if result == -1:             # <<<<<<<<<<<<<<
@@ -9296,7 +9131,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
  */
       }
 
-      /* "pywrapfst.pyx":723
+      /* "pywrapfst.pyx":738
  *       KeyError: Key not found.
  *     """
  *     try:             # <<<<<<<<<<<<<<
@@ -9313,25 +9148,25 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-    /* "pywrapfst.pyx":727
+    /* "pywrapfst.pyx":742
  *       if result == -1:
  *         raise KeyError(key)
  *     except FstArgError:             # <<<<<<<<<<<<<<
  *       result = self._table.FindSymbol(key)
  *       if result == b"":
  */
-    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 727, __pyx_L5_except_error)
+    __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 742, __pyx_L5_except_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     if (__pyx_t_8) {
       __Pyx_AddTraceback("pywrapfst._SymbolTable.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_5, &__pyx_t_9) < 0) __PYX_ERR(0, 727, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_5, &__pyx_t_9) < 0) __PYX_ERR(0, 742, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GOTREF(__pyx_t_9);
 
-      /* "pywrapfst.pyx":728
+      /* "pywrapfst.pyx":743
  *         raise KeyError(key)
  *     except FstArgError:
  *       result = self._table.FindSymbol(key)             # <<<<<<<<<<<<<<
@@ -9340,44 +9175,44 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
  */
       if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-        __PYX_ERR(0, 728, __pyx_L5_except_error)
+        __PYX_ERR(0, 743, __pyx_L5_except_error)
       }
-      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L5_except_error)
-      __pyx_t_11 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_self->_table->Find(__pyx_t_10)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 728, __pyx_L5_except_error)
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 743, __pyx_L5_except_error)
+      __pyx_t_11 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_self->_table->Find(__pyx_t_10)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 743, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_XDECREF_SET(__pyx_v_result, __pyx_t_11);
       __pyx_t_11 = 0;
 
-      /* "pywrapfst.pyx":729
+      /* "pywrapfst.pyx":744
  *     except FstArgError:
  *       result = self._table.FindSymbol(key)
  *       if result == b"":             # <<<<<<<<<<<<<<
  *         raise KeyError(key)
  *     return result
  */
-      __pyx_t_6 = (__Pyx_PyBytes_Equals(__pyx_v_result, __pyx_kp_b_, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 729, __pyx_L5_except_error)
+      __pyx_t_6 = (__Pyx_PyBytes_Equals(__pyx_v_result, __pyx_kp_b__5, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 744, __pyx_L5_except_error)
       if (__pyx_t_6) {
 
-        /* "pywrapfst.pyx":730
+        /* "pywrapfst.pyx":745
  *       result = self._table.FindSymbol(key)
  *       if result == b"":
  *         raise KeyError(key)             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-        __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 730, __pyx_L5_except_error)
+        __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 745, __pyx_L5_except_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_INCREF(__pyx_v_key);
         __Pyx_GIVEREF(__pyx_v_key);
         PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_key);
-        __pyx_t_12 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 730, __pyx_L5_except_error)
+        __pyx_t_12 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 745, __pyx_L5_except_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __Pyx_Raise(__pyx_t_12, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __PYX_ERR(0, 730, __pyx_L5_except_error)
+        __PYX_ERR(0, 745, __pyx_L5_except_error)
 
-        /* "pywrapfst.pyx":729
+        /* "pywrapfst.pyx":744
  *     except FstArgError:
  *       result = self._table.FindSymbol(key)
  *       if result == b"":             # <<<<<<<<<<<<<<
@@ -9393,7 +9228,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":723
+    /* "pywrapfst.pyx":738
  *       KeyError: Key not found.
  *     """
  *     try:             # <<<<<<<<<<<<<<
@@ -9415,19 +9250,19 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
     __pyx_L10_try_end:;
   }
 
-  /* "pywrapfst.pyx":731
+  /* "pywrapfst.pyx":746
  *       if result == b"":
  *         raise KeyError(key)
  *     return result             # <<<<<<<<<<<<<<
  * 
- *   cpdef bool member(self, key):
+ *   cpdef int64 get_nth_key(self, ssize_t pos) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(__pyx_v_result);
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":704
+  /* "pywrapfst.pyx":719
  *     return _init_SymbolTable(self._table.Copy())
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9451,331 +9286,15 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10find(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":733
+/* "pywrapfst.pyx":748
  *     return result
  * 
- *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
- *     """
- *     member(self, key)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch) {
-  bool __pyx_r;
-  __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;
-  bool __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
-  PyObject *__pyx_t_9 = NULL;
-  std::string __pyx_t_10;
-  int __pyx_t_11;
-  __pyx_t_10basictypes_int64 __pyx_t_12;
-  __Pyx_RefNannySetupContext("member", 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)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 733, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_13member)) {
-      __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))) {
-        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
-        if (likely(__pyx_t_4)) {
-          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-          __Pyx_INCREF(__pyx_t_4);
-          __Pyx_INCREF(function);
-          __Pyx_DECREF_SET(__pyx_t_3, function);
-        }
-      }
-      if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_2);
-      } else {
-        #if CYTHON_FAST_PYCALL
-        if (PyFunction_Check(__pyx_t_3)) {
-          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error)
-          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-          __Pyx_GOTREF(__pyx_t_2);
-        } else
-        #endif
-        #if CYTHON_FAST_PYCCALL
-        if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
-          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error)
-          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-          __Pyx_GOTREF(__pyx_t_2);
-        } else
-        #endif
-        {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 733, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_5);
-          __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
-          __Pyx_INCREF(__pyx_v_key);
-          __Pyx_GIVEREF(__pyx_v_key);
-          PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_key);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_2);
-          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        }
-      }
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_6 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 733, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_r = __pyx_t_6;
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      goto __pyx_L0;
-    }
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  }
-
-  /* "pywrapfst.pyx":749
- *       Whether or not the key is present (as a string or a index) in the table.
- *     """
- *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
- *     except FstArgError:
- */
-  {
-    __Pyx_PyThreadState_declare
-    __Pyx_PyThreadState_assign
-    __Pyx_ExceptionSave(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
-    __Pyx_XGOTREF(__pyx_t_7);
-    __Pyx_XGOTREF(__pyx_t_8);
-    __Pyx_XGOTREF(__pyx_t_9);
-    /*try:*/ {
-
-      /* "pywrapfst.pyx":750
- *     """
- *     try:
- *       return self._table.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
- *     except FstArgError:
- *       return self._table.MemberIndex(key)
- */
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-        __PYX_ERR(0, 750, __pyx_L3_error)
-      }
-      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 750, __pyx_L3_error)
-      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_10);
-      goto __pyx_L7_try_return;
-
-      /* "pywrapfst.pyx":749
- *       Whether or not the key is present (as a string or a index) in the table.
- *     """
- *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
- *     except FstArgError:
- */
-    }
-    __pyx_L3_error:;
-    __Pyx_PyThreadState_assign
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
-
-    /* "pywrapfst.pyx":751
- *     try:
- *       return self._table.MemberSymbol(tostring(key))
- *     except FstArgError:             # <<<<<<<<<<<<<<
- *       return self._table.MemberIndex(key)
- * 
- */
-    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 751, __pyx_L5_except_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (__pyx_t_11) {
-      __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 751, __pyx_L5_except_error)
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_GOTREF(__pyx_t_3);
-
-      /* "pywrapfst.pyx":752
- *       return self._table.MemberSymbol(tostring(key))
- *     except FstArgError:
- *       return self._table.MemberIndex(key)             # <<<<<<<<<<<<<<
- * 
- *   def __contains__(self, key):
- */
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-        __PYX_ERR(0, 752, __pyx_L5_except_error)
-      }
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 752, __pyx_L5_except_error)
-      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_12);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      goto __pyx_L6_except_return;
-    }
-    goto __pyx_L5_except_error;
-    __pyx_L5_except_error:;
-
-    /* "pywrapfst.pyx":749
- *       Whether or not the key is present (as a string or a index) in the table.
- *     """
- *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
- *     except FstArgError:
- */
-    __Pyx_PyThreadState_assign
-    __Pyx_XGIVEREF(__pyx_t_7);
-    __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_XGIVEREF(__pyx_t_9);
-    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
-    goto __pyx_L1_error;
-    __pyx_L7_try_return:;
-    __Pyx_PyThreadState_assign
-    __Pyx_XGIVEREF(__pyx_t_7);
-    __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_XGIVEREF(__pyx_t_9);
-    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
-    goto __pyx_L0;
-    __pyx_L6_except_return:;
-    __Pyx_PyThreadState_assign
-    __Pyx_XGIVEREF(__pyx_t_7);
-    __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_XGIVEREF(__pyx_t_9);
-    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
-    goto __pyx_L0;
-  }
-
-  /* "pywrapfst.pyx":733
- *     return result
- * 
- *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
- *     """
- *     member(self, key)
- */
-
-  /* function exit code */
-  __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_WriteUnraisable("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_12member[] = "\n    member(self, key)\n\n    Given a symbol or index, returns whether it is found in the table.\n\n    This method returns a boolean indicating whether the given symbol or index\n    is present in the table. If one intends to perform subsequent lookup, it is\n    much better to simply call the find method, catching the KeyError.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      Whether or not the key is present (as a string or a index) in the table.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13member(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("member (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_12member(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("member", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_12_SymbolTable_member(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 733, __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._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":754
- *       return self._table.MemberIndex(key)
- * 
- *   def __contains__(self, key):             # <<<<<<<<<<<<<<
- *     return self.member(key)
- * 
- */
-
-/* Python wrapper */
-static int __pyx_pw_9pywrapfst_12_SymbolTable_15__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static int __pyx_pw_9pywrapfst_12_SymbolTable_15__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_14__contains__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static int __pyx_pf_9pywrapfst_12_SymbolTable_14__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__contains__", 0);
-
-  /* "pywrapfst.pyx":755
- * 
- *   def __contains__(self, key):
- *     return self.member(key)             # <<<<<<<<<<<<<<
- * 
- *   cpdef int64 get_nth_key(self, ssize_t pos) except *:
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "member");
-    __PYX_ERR(0, 755, __pyx_L1_error)
-  }
-  __pyx_r = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, __pyx_v_key, 0);
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":754
- *       return self._table.MemberIndex(key)
- * 
- *   def __contains__(self, key):             # <<<<<<<<<<<<<<
- *     return self.member(key)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = -1;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":757
- *     return self.member(key)
- * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
  *     get_nth_key(self, pos)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
 static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch) {
   __pyx_t_10basictypes_int64 __pyx_v_result;
   __pyx_t_10basictypes_int64 __pyx_r;
@@ -9793,10 +9312,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 757, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 748, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key)) {
-      __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 757, __pyx_L1_error)
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_13get_nth_key)) {
+      __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 748, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -9810,14 +9329,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -9826,26 +9345,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 757, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 748, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_7 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_7 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 757, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_7 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 748, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_7;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9854,7 +9373,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":772
+  /* "pywrapfst.pyx":763
  *       KeyError: index not found.
  *     """
  *     cdef int64 result = self._table.GetNthKey(pos)             # <<<<<<<<<<<<<<
@@ -9863,11 +9382,11 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 772, __pyx_L1_error)
+    __PYX_ERR(0, 763, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_table->GetNthKey(__pyx_v_pos);
 
-  /* "pywrapfst.pyx":773
+  /* "pywrapfst.pyx":764
  *     """
  *     cdef int64 result = self._table.GetNthKey(pos)
  *     if result == -1:             # <<<<<<<<<<<<<<
@@ -9877,28 +9396,28 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
   __pyx_t_8 = ((__pyx_v_result == -1L) != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":774
+    /* "pywrapfst.pyx":765
  *     cdef int64 result = self._table.GetNthKey(pos)
  *     if result == -1:
  *       raise KeyError(pos)             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error)
+    __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 765, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 774, __pyx_L1_error)
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 765, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_1);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
     __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 765, __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, 774, __pyx_L1_error)
+    __PYX_ERR(0, 765, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":773
+    /* "pywrapfst.pyx":764
  *     """
  *     cdef int64 result = self._table.GetNthKey(pos)
  *     if result == -1:             # <<<<<<<<<<<<<<
@@ -9907,7 +9426,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
  */
   }
 
-  /* "pywrapfst.pyx":775
+  /* "pywrapfst.pyx":766
  *     if result == -1:
  *       raise KeyError(pos)
  *     return result             # <<<<<<<<<<<<<<
@@ -9917,8 +9436,8 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":757
- *     return self.member(key)
+  /* "pywrapfst.pyx":748
+ *     return result
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -9941,15 +9460,15 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_16get_nth_key[] = "\n    get_nth_key(self, pos)\n\n    Retrieves the integer index of the n-th key in the table.\n\n    Args:\n      pos: The n-th key to retrieve.\n\n    Returns:\n      The integer index of the n-th key.\n\n    Raises:\n      KeyError: index not found.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_12get_nth_key[] = "\n    get_nth_key(self, pos)\n\n    Retrieves the integer index of the n-th key in the table.\n\n    Args:\n      pos: The n-th key to retrieve.\n\n    Returns:\n      The integer index of the n-th key.\n\n    Raises:\n      KeyError: index not found.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos) {
   Py_ssize_t __pyx_v_pos;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_nth_key (wrapper)", 0);
   assert(__pyx_arg_pos); {
-    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 757, __pyx_L3_error)
+    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 748, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -9957,22 +9476,22 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key(PyObject *__py
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_16get_nth_key(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((Py_ssize_t)__pyx_v_pos));
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_12get_nth_key(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((Py_ssize_t)__pyx_v_pos));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos) {
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __pyx_t_10basictypes_int64 __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("get_nth_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 757, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 748, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9989,15 +9508,15 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16get_nth_key(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":777
+/* "pywrapfst.pyx":768
  *     return result
  * 
  *   cpdef string labeled_checksum(self):             # <<<<<<<<<<<<<<
- *     return self._table.LabeledCheckSum()
- * 
+ *     """
+ *     labeled_checksum(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -10011,9 +9530,9 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __p
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 777, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 768, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_19labeled_checksum)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_15labeled_checksum)) {
       __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))) {
@@ -10026,14 +9545,14 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __p
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 777, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 768, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 777, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 768, __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, 777, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 768, __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;
@@ -10042,26 +9561,26 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __p
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":778
- * 
- *   cpdef string labeled_checksum(self):
+  /* "pywrapfst.pyx":774
+ *     Returns a string indicating the label-dependent MD5 checksum for the table.
+ *     """
  *     return self._table.LabeledCheckSum()             # <<<<<<<<<<<<<<
  * 
- *   cpdef string name(self):
+ *   cpdef bool member(self, key):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 778, __pyx_L1_error)
+    __PYX_ERR(0, 774, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_table->LabeledCheckSum();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":777
+  /* "pywrapfst.pyx":768
  *     return result
  * 
  *   cpdef string labeled_checksum(self):             # <<<<<<<<<<<<<<
- *     return self._table.LabeledCheckSum()
- * 
+ *     """
+ *     labeled_checksum(self)
  */
 
   /* function exit code */
@@ -10077,25 +9596,26 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __p
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_14labeled_checksum[] = "\n    labeled_checksum(self)\n\n    Returns a string indicating the label-dependent MD5 checksum for the table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("labeled_checksum (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_18labeled_checksum(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_14labeled_checksum(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("labeled_checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 777, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 768, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10112,12 +9632,328 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18labeled_checksum(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":780
+/* "pywrapfst.pyx":776
  *     return self._table.LabeledCheckSum()
  * 
- *   cpdef string name(self):             # <<<<<<<<<<<<<<
- *     return self._table.Name()
+ *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
+ *     """
+ *     member(self, key)
+ */
+
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch) {
+  bool __pyx_r;
+  __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;
+  bool __pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  std::string __pyx_t_10;
+  int __pyx_t_11;
+  __pyx_t_10basictypes_int64 __pyx_t_12;
+  __Pyx_RefNannySetupContext("member", 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)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 776, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_17member)) {
+      __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))) {
+        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_4)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+        }
+      }
+      if (!__pyx_t_4) {
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 776, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_2);
+      } else {
+        #if CYTHON_FAST_PYCALL
+        if (PyFunction_Check(__pyx_t_3)) {
+          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 776, __pyx_L1_error)
+          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __Pyx_GOTREF(__pyx_t_2);
+        } else
+        #endif
+        #if CYTHON_FAST_PYCCALL
+        if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
+          PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 776, __pyx_L1_error)
+          __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+          __Pyx_GOTREF(__pyx_t_2);
+        } else
+        #endif
+        {
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 776, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_5);
+          __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
+          __Pyx_INCREF(__pyx_v_key);
+          __Pyx_GIVEREF(__pyx_v_key);
+          PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_key);
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 776, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_2);
+          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        }
+      }
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_6 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 776, __pyx_L1_error)
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __pyx_r = __pyx_t_6;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "pywrapfst.pyx":792
+ *       Whether or not the key is present (as a string or a index) in the table.
+ *     """
+ *     try:             # <<<<<<<<<<<<<<
+ *       return self._table.MemberSymbol(tostring(key))
+ *     except FstArgError:
+ */
+  {
+    __Pyx_PyThreadState_declare
+    __Pyx_PyThreadState_assign
+    __Pyx_ExceptionSave(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
+    __Pyx_XGOTREF(__pyx_t_7);
+    __Pyx_XGOTREF(__pyx_t_8);
+    __Pyx_XGOTREF(__pyx_t_9);
+    /*try:*/ {
+
+      /* "pywrapfst.pyx":793
+ *     """
+ *     try:
+ *       return self._table.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
+ *     except FstArgError:
+ *       return self._table.MemberIndex(key)
+ */
+      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
+        __PYX_ERR(0, 793, __pyx_L3_error)
+      }
+      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 793, __pyx_L3_error)
+      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_10);
+      goto __pyx_L7_try_return;
+
+      /* "pywrapfst.pyx":792
+ *       Whether or not the key is present (as a string or a index) in the table.
+ *     """
+ *     try:             # <<<<<<<<<<<<<<
+ *       return self._table.MemberSymbol(tostring(key))
+ *     except FstArgError:
+ */
+    }
+    __pyx_L3_error:;
+    __Pyx_PyThreadState_assign
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+    /* "pywrapfst.pyx":794
+ *     try:
+ *       return self._table.MemberSymbol(tostring(key))
+ *     except FstArgError:             # <<<<<<<<<<<<<<
+ *       return self._table.MemberIndex(key)
+ * 
+ */
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 794, __pyx_L5_except_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_11) {
+      __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 794, __pyx_L5_except_error)
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_GOTREF(__pyx_t_3);
+
+      /* "pywrapfst.pyx":795
+ *       return self._table.MemberSymbol(tostring(key))
+ *     except FstArgError:
+ *       return self._table.MemberIndex(key)             # <<<<<<<<<<<<<<
+ * 
+ *   def __contains__(self, key):
+ */
+      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
+        __PYX_ERR(0, 795, __pyx_L5_except_error)
+      }
+      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 795, __pyx_L5_except_error)
+      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_12);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      goto __pyx_L6_except_return;
+    }
+    goto __pyx_L5_except_error;
+    __pyx_L5_except_error:;
+
+    /* "pywrapfst.pyx":792
+ *       Whether or not the key is present (as a string or a index) in the table.
+ *     """
+ *     try:             # <<<<<<<<<<<<<<
+ *       return self._table.MemberSymbol(tostring(key))
+ *     except FstArgError:
+ */
+    __Pyx_PyThreadState_assign
+    __Pyx_XGIVEREF(__pyx_t_7);
+    __Pyx_XGIVEREF(__pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
+    goto __pyx_L1_error;
+    __pyx_L7_try_return:;
+    __Pyx_PyThreadState_assign
+    __Pyx_XGIVEREF(__pyx_t_7);
+    __Pyx_XGIVEREF(__pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
+    goto __pyx_L0;
+    __pyx_L6_except_return:;
+    __Pyx_PyThreadState_assign
+    __Pyx_XGIVEREF(__pyx_t_7);
+    __Pyx_XGIVEREF(__pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
+    goto __pyx_L0;
+  }
+
+  /* "pywrapfst.pyx":776
+ *     return self._table.LabeledCheckSum()
+ * 
+ *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
+ *     """
+ *     member(self, key)
+ */
+
+  /* function exit code */
+  __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_WriteUnraisable("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_16member[] = "\n    member(self, key)\n\n    Given a symbol or index, returns whether it is found in the table.\n\n    This method returns a boolean indicating whether the given symbol or index\n    is present in the table. If one intends to perform subsequent lookup, it is\n    better to simply call the find method, catching the KeyError.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      Whether or not the key is present (as a string or a index) in the table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17member(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("member (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_16member(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("member", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_12_SymbolTable_member(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 776, __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._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":797
+ *       return self._table.MemberIndex(key)
+ * 
+ *   def __contains__(self, key):             # <<<<<<<<<<<<<<
+ *     return self.member(key)
+ * 
+ */
+
+/* Python wrapper */
+static int __pyx_pw_9pywrapfst_12_SymbolTable_19__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static int __pyx_pw_9pywrapfst_12_SymbolTable_19__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_18__contains__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_9pywrapfst_12_SymbolTable_18__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__contains__", 0);
+
+  /* "pywrapfst.pyx":798
+ * 
+ *   def __contains__(self, key):
+ *     return self.member(key)             # <<<<<<<<<<<<<<
  * 
+ *   cpdef string name(self):
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "member");
+    __PYX_ERR(0, 798, __pyx_L1_error)
+  }
+  __pyx_r = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, __pyx_v_key, 0);
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":797
+ *       return self._table.MemberIndex(key)
+ * 
+ *   def __contains__(self, key):             # <<<<<<<<<<<<<<
+ *     return self.member(key)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("pywrapfst._SymbolTable.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":800
+ *     return self.member(key)
+ * 
+ *   cpdef string name(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     name(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -10134,7 +9970,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 800, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_21name)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -10149,14 +9985,14 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 800, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 800, __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, 780, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 800, __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;
@@ -10165,26 +10001,26 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":781
- * 
- *   cpdef string name(self):
+  /* "pywrapfst.pyx":806
+ *     Returns the symbol table's name.
+ *     """
  *     return self._table.Name()             # <<<<<<<<<<<<<<
  * 
  *   cpdef size_t num_symbols(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 781, __pyx_L1_error)
+    __PYX_ERR(0, 806, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_table->Name();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":780
- *     return self._table.LabeledCheckSum()
+  /* "pywrapfst.pyx":800
+ *     return self.member(key)
  * 
  *   cpdef string name(self):             # <<<<<<<<<<<<<<
- *     return self._table.Name()
- * 
+ *     """
+ *     name(self)
  */
 
   /* function exit code */
@@ -10201,6 +10037,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_20name[] = "\n    name(self)\n\n    Returns the symbol table's name.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -10218,7 +10055,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_20name(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_name(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_name(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 800, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10235,12 +10072,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_20name(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":783
+/* "pywrapfst.pyx":808
  *     return self._table.Name()
  * 
  *   cpdef size_t num_symbols(self):             # <<<<<<<<<<<<<<
- *     return self._table.NumSymbols()
- * 
+ *     """
+ *     num_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -10257,7 +10094,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 808, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -10272,14 +10109,14 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __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, 783, __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, 808, __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;
@@ -10288,26 +10125,26 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":784
- * 
- *   cpdef size_t num_symbols(self):
+  /* "pywrapfst.pyx":814
+ *     Returns the number of symbols in the symbol table.
+ *     """
  *     return self._table.NumSymbols()             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write(self, filename) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 784, __pyx_L1_error)
+    __PYX_ERR(0, 814, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_table->NumSymbols();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":783
+  /* "pywrapfst.pyx":808
  *     return self._table.Name()
  * 
  *   cpdef size_t num_symbols(self):             # <<<<<<<<<<<<<<
- *     return self._table.NumSymbols()
- * 
+ *     """
+ *     num_symbols(self)
  */
 
   /* function exit code */
@@ -10325,6 +10162,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12_SymbolTable_22num_symbols[] = "\n    num_symbols(self)\n\n    Returns the number of symbols in the symbol table.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -10342,7 +10180,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22num_symbols(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_12_SymbolTable_num_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_12_SymbolTable_num_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 808, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10359,7 +10197,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22num_symbols(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":786
+/* "pywrapfst.pyx":816
  *     return self._table.NumSymbols()
  * 
  *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -10383,7 +10221,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 786, __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, 816, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_25write)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -10398,13 +10236,13 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -10412,19 +10250,19 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 786, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 816, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_filename);
           __Pyx_GIVEREF(__pyx_v_filename);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_filename);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -10437,7 +10275,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":800
+  /* "pywrapfst.pyx":830
  *       FstIOError: Write failed.
  *     """
  *     if not self._table.Write(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -10446,22 +10284,22 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 800, __pyx_L1_error)
+    __PYX_ERR(0, 830, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 800, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 830, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_v_self->_table->Write(__pyx_t_6) != 0)) != 0);
   if (__pyx_t_7) {
 
-    /* "pywrapfst.pyx":801
+    /* "pywrapfst.pyx":831
  *     """
  *     if not self._table.Write(tostring(filename)):
  *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write_text(self, filename) except *:
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 801, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 831, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 801, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 831, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -10474,13 +10312,13 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
       }
     }
     if (!__pyx_t_4) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 831, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
@@ -10488,19 +10326,19 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __pyx_t_4 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -10517,14 +10355,14 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 801, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 831, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 831, __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;
@@ -10533,20 +10371,20 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 831, __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;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_3);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 801, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 831, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -10554,9 +10392,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     __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, 801, __pyx_L1_error)
+    __PYX_ERR(0, 831, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":800
+    /* "pywrapfst.pyx":830
  *       FstIOError: Write failed.
  *     """
  *     if not self._table.Write(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -10565,7 +10403,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
  */
   }
 
-  /* "pywrapfst.pyx":786
+  /* "pywrapfst.pyx":816
  *     return self._table.NumSymbols()
  * 
  *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -10607,8 +10445,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24write(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12_SymbolTable_write(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 786, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 786, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12_SymbolTable_write(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 816, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 816, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10625,7 +10463,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":803
+/* "pywrapfst.pyx":833
  *       raise FstIOError("Write failed: {!r}".format(filename))
  * 
  *   cpdef void write_text(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -10649,7 +10487,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 803, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 833, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_27write_text)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -10664,13 +10502,13 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 803, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 833, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 803, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 833, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -10678,19 +10516,19 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 803, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 833, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 803, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 833, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_filename);
           __Pyx_GIVEREF(__pyx_v_filename);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_filename);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 803, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 833, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -10703,7 +10541,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":817
+  /* "pywrapfst.pyx":847
  *       FstIOError: Write failed.
  *     """
  *     if not self._table.WriteText(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -10712,22 +10550,22 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 817, __pyx_L1_error)
+    __PYX_ERR(0, 847, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 817, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 847, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_v_self->_table->WriteText(__pyx_t_6) != 0)) != 0);
   if (__pyx_t_7) {
 
-    /* "pywrapfst.pyx":818
+    /* "pywrapfst.pyx":848
  *     """
  *     if not self._table.WriteText(tostring(filename)):
  *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 818, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 848, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 818, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 848, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -10740,13 +10578,13 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
       }
     }
     if (!__pyx_t_4) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 818, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 848, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
@@ -10754,19 +10592,19 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __pyx_t_4 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -10783,14 +10621,14 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 818, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __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;
@@ -10799,20 +10637,20 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __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;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_3);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 818, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 848, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -10820,9 +10658,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     __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, 818, __pyx_L1_error)
+    __PYX_ERR(0, 848, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":817
+    /* "pywrapfst.pyx":847
  *       FstIOError: Write failed.
  *     """
  *     if not self._table.WriteText(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -10831,7 +10669,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
  */
   }
 
-  /* "pywrapfst.pyx":803
+  /* "pywrapfst.pyx":833
  *       raise FstIOError("Write failed: {!r}".format(filename))
  * 
  *   cpdef void write_text(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -10873,8 +10711,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write_text(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write_text", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12_SymbolTable_write_text(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 803, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 803, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12_SymbolTable_write_text(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 833, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 833, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10891,7 +10729,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write_text(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":836
+/* "pywrapfst.pyx":866
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -10924,7 +10762,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":837
+  /* "pywrapfst.pyx":867
  * 
  *   def __repr__(self):
  *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
@@ -10932,28 +10770,28 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_const_EncodeMapper_SymbolTable, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 837, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_const_EncodeMapper_SymbolTable, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 867, __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 '%s'", "name");
-    __PYX_ERR(0, 837, __pyx_L1_error)
+    __PYX_ERR(0, 867, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 837, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 867, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":838
+  /* "pywrapfst.pyx":868
  *   def __repr__(self):
  *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
  *                                                                     id(self))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 838, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 868, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 838, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 868, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -10971,7 +10809,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 837, __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, 867, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -10981,7 +10819,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 837, __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, 867, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -10989,7 +10827,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 837, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 867, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -11000,7 +10838,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 837, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 867, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -11009,7 +10847,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":836
+  /* "pywrapfst.pyx":866
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11033,7 +10871,7 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":855
+/* "pywrapfst.pyx":885
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11066,7 +10904,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":856
+  /* "pywrapfst.pyx":886
  * 
  *   def __repr__(self):
  *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
@@ -11074,28 +10912,28 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_const_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 856, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_const_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 886, __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 '%s'", "name");
-    __PYX_ERR(0, 856, __pyx_L1_error)
+    __PYX_ERR(0, 886, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 856, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 886, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":857
+  /* "pywrapfst.pyx":887
  *   def __repr__(self):
  *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
  *                                                            id(self))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 857, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 887, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 857, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 887, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -11113,7 +10951,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 856, __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, 886, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11123,7 +10961,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 856, __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, 886, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11131,7 +10969,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 856, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 886, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -11142,7 +10980,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 856, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 886, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -11151,7 +10989,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":855
+  /* "pywrapfst.pyx":885
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11175,7 +11013,7 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":871
+/* "pywrapfst.pyx":901
  *   """
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=-1):             # <<<<<<<<<<<<<<
@@ -11209,10 +11047,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 871, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 901, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol)) {
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 871, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 901, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -11230,7 +11068,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 871, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11239,14 +11077,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 871, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       } else
       #endif
       {
-        __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 871, __pyx_L1_error)
+        __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 901, __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;
@@ -11257,12 +11095,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
         __Pyx_GIVEREF(__pyx_t_3);
         PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 871, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 871, __pyx_L1_error)
+      __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 901, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_8;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -11271,20 +11109,20 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":887
+  /* "pywrapfst.pyx":917
  *       The integer key of the new symbol.
  *     """
  *     cdef symbol_string = tostring(symbol)             # <<<<<<<<<<<<<<
  *     if key != -1:
  *       return self._table.AddSymbol(symbol_string, key)
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 887, __pyx_L1_error)
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 917, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_symbol_string = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":888
+  /* "pywrapfst.pyx":918
  *     """
  *     cdef symbol_string = tostring(symbol)
  *     if key != -1:             # <<<<<<<<<<<<<<
@@ -11294,7 +11132,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   __pyx_t_10 = ((__pyx_v_key != -1L) != 0);
   if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":889
+    /* "pywrapfst.pyx":919
  *     cdef symbol_string = tostring(symbol)
  *     if key != -1:
  *       return self._table.AddSymbol(symbol_string, key)             # <<<<<<<<<<<<<<
@@ -11303,13 +11141,13 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 889, __pyx_L1_error)
+      __PYX_ERR(0, 919, __pyx_L1_error)
     }
-    __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_v_symbol_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 889, __pyx_L1_error)
+    __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_v_symbol_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 919, __pyx_L1_error)
     __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_t_9, __pyx_v_key);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":888
+    /* "pywrapfst.pyx":918
  *     """
  *     cdef symbol_string = tostring(symbol)
  *     if key != -1:             # <<<<<<<<<<<<<<
@@ -11318,7 +11156,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
  */
   }
 
-  /* "pywrapfst.pyx":891
+  /* "pywrapfst.pyx":921
  *       return self._table.AddSymbol(symbol_string, key)
  *     else:
  *       return self._table.AddSymbol(symbol_string)             # <<<<<<<<<<<<<<
@@ -11328,14 +11166,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 891, __pyx_L1_error)
+      __PYX_ERR(0, 921, __pyx_L1_error)
     }
-    __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_v_symbol_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 891, __pyx_L1_error)
+    __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_v_symbol_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 921, __pyx_L1_error)
     __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_t_9);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":871
+  /* "pywrapfst.pyx":901
  *   """
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=-1):             # <<<<<<<<<<<<<<
@@ -11392,7 +11230,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 871, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 901, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -11404,14 +11242,14 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
     }
     __pyx_v_symbol = values[0];
     if (values[1]) {
-      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 871, __pyx_L3_error)
+      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 901, __pyx_L3_error)
     } else {
       __pyx_v_key = ((__pyx_t_10basictypes_int64)-1L);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 871, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 901, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -11435,7 +11273,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.key = __pyx_v_key;
   __pyx_t_1 = __pyx_vtabptr_9pywrapfst__MutableSymbolTable->add_symbol(__pyx_v_self, __pyx_v_symbol, 1, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 871, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 901, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -11452,7 +11290,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":893
+/* "pywrapfst.pyx":923
  *       return self._table.AddSymbol(symbol_string)
  * 
  *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -11473,7 +11311,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 893, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 923, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -11488,13 +11326,13 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 893, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 893, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -11502,19 +11340,19 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 893, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 893, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 923, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(((PyObject *)__pyx_v_syms));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_syms));
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, ((PyObject *)__pyx_v_syms));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 893, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -11527,7 +11365,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":905
+  /* "pywrapfst.pyx":935
  *       syms: A SymbolTable to be merged with the current table.
  *     """
  *     self._table.AddTable(deref(syms._table))             # <<<<<<<<<<<<<<
@@ -11536,15 +11374,15 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 905, __pyx_L1_error)
+    __PYX_ERR(0, 935, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 905, __pyx_L1_error)
+    __PYX_ERR(0, 935, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base._table->AddTable((*__pyx_v_syms->_table));
 
-  /* "pywrapfst.pyx":893
+  /* "pywrapfst.pyx":923
  *       return self._table.AddSymbol(symbol_string)
  * 
  *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -11572,7 +11410,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 893, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 923, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(((struct __pyx_obj_9pywrapfst__MutableSymbolTable *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -11590,7 +11428,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("add_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_syms, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 893, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_syms, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 923, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11607,7 +11445,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":907
+/* "pywrapfst.pyx":937
  *     self._table.AddTable(deref(syms._table))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -11629,7 +11467,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 907, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 937, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19_MutableSymbolTable_5set_name)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -11644,13 +11482,13 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_new_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_new_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_new_name};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -11658,19 +11496,19 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_new_name};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 907, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 937, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_new_name);
           __Pyx_GIVEREF(__pyx_v_new_name);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_new_name);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -11683,7 +11521,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":908
+  /* "pywrapfst.pyx":938
  * 
  *   cpdef void set_name(self, new_name) except *:
  *     self._table.SetName(tostring(new_name))             # <<<<<<<<<<<<<<
@@ -11692,12 +11530,12 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 908, __pyx_L1_error)
+    __PYX_ERR(0, 938, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 908, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L1_error)
   __pyx_v_self->__pyx_base._table->SetName(__pyx_t_6);
 
-  /* "pywrapfst.pyx":907
+  /* "pywrapfst.pyx":937
  *     self._table.AddTable(deref(syms._table))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
@@ -11737,8 +11575,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 907, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 907, __pyx_L1_error)
+  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 937, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 937, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11755,7 +11593,7 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":927
+/* "pywrapfst.pyx":948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11788,7 +11626,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":928
+  /* "pywrapfst.pyx":949
  * 
  *   def __repr__(self):
  *     return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
@@ -11796,20 +11634,20 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 928, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 949, __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 '%s'", "name");
-    __PYX_ERR(0, 928, __pyx_L1_error)
+    __PYX_ERR(0, 949, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 928, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 928, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 928, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 949, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -11827,7 +11665,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 928, __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, 949, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11837,7 +11675,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 928, __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, 949, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11845,7 +11683,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 928, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 949, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -11856,7 +11694,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 928, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 949, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -11865,7 +11703,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":927
+  /* "pywrapfst.pyx":948
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11889,7 +11727,7 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":956
+/* "pywrapfst.pyx":969
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11922,7 +11760,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":957
+  /* "pywrapfst.pyx":970
  * 
  *   def __repr__(self):
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
@@ -11930,20 +11768,20 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
  *   def __init__(self, name=b"<unspecified>"):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 957, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 970, __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 '%s'", "name");
-    __PYX_ERR(0, 957, __pyx_L1_error)
+    __PYX_ERR(0, 970, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 957, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 970, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 957, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 970, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 957, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 970, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -11961,7 +11799,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 957, __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, 970, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11971,7 +11809,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 957, __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, 970, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11979,7 +11817,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 957, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 970, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -11990,7 +11828,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 957, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 970, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -11999,7 +11837,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":956
+  /* "pywrapfst.pyx":969
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -12023,7 +11861,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":959
+/* "pywrapfst.pyx":972
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name=b"<unspecified>"):             # <<<<<<<<<<<<<<
@@ -12059,7 +11897,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 959, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 972, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12072,7 +11910,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 959, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 972, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12091,21 +11929,21 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   std::string __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":960
+  /* "pywrapfst.pyx":973
  * 
  *   def __init__(self, name=b"<unspecified>"):
  *     self._table = new fst.SymbolTable(tostring(name))             # <<<<<<<<<<<<<<
  *     self._smart_table.reset(self._table)
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 960, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 973, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 960, __pyx_L1_error)
+    __PYX_ERR(0, 973, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base.__pyx_base._table = new fst::SymbolTable(__pyx_t_1);
 
-  /* "pywrapfst.pyx":961
+  /* "pywrapfst.pyx":974
  *   def __init__(self, name=b"<unspecified>"):
  *     self._table = new fst.SymbolTable(tostring(name))
  *     self._smart_table.reset(self._table)             # <<<<<<<<<<<<<<
@@ -12114,15 +11952,15 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_smart_table");
-    __PYX_ERR(0, 961, __pyx_L1_error)
+    __PYX_ERR(0, 974, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 961, __pyx_L1_error)
+    __PYX_ERR(0, 974, __pyx_L1_error)
   }
   __pyx_v_self->_smart_table.reset(__pyx_v_self->__pyx_base.__pyx_base._table);
 
-  /* "pywrapfst.pyx":959
+  /* "pywrapfst.pyx":972
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name=b"<unspecified>"):             # <<<<<<<<<<<<<<
@@ -12141,7 +11979,7 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":964
+/* "pywrapfst.pyx":977
  * 
  *   @classmethod
  *   def read(cls, filename):             # <<<<<<<<<<<<<<
@@ -12177,17 +12015,17 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":980
+  /* "pywrapfst.pyx":993
  *     See also: `SymbolTable.read_fst`, `SymbolTable.read_text`.
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.Read(tostring(filename))             # <<<<<<<<<<<<<<
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 980, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 993, __pyx_L1_error)
   __pyx_v_tsyms = fst::SymbolTable::Read(__pyx_t_1);
 
-  /* "pywrapfst.pyx":981
+  /* "pywrapfst.pyx":994
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.Read(tostring(filename))
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12197,16 +12035,16 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   __pyx_t_2 = ((__pyx_v_tsyms == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":982
+    /* "pywrapfst.pyx":995
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.Read(tostring(filename))
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(tsyms)
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 982, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 995, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 982, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 995, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12219,13 +12057,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 982, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 995, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -12233,19 +12071,19 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12262,14 +12100,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 982, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -12278,20 +12116,20 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 982, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12299,9 +12137,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
     __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, 982, __pyx_L1_error)
+    __PYX_ERR(0, 995, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":981
+    /* "pywrapfst.pyx":994
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.Read(tostring(filename))
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12310,7 +12148,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
  */
   }
 
-  /* "pywrapfst.pyx":983
+  /* "pywrapfst.pyx":996
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))
  *     return _init_SymbolTable(tsyms)             # <<<<<<<<<<<<<<
@@ -12318,13 +12156,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 983, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 996, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":964
+  /* "pywrapfst.pyx":977
  * 
  *   @classmethod
  *   def read(cls, filename):             # <<<<<<<<<<<<<<
@@ -12348,7 +12186,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":986
+/* "pywrapfst.pyx":999
  * 
  *   @classmethod
  *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12389,7 +12227,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 986, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 999, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12401,14 +12239,14 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
     }
     __pyx_v_filename = values[0];
     if (values[1]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 986, __pyx_L3_error)
+      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 999, __pyx_L3_error)
     } else {
       __pyx_v_allow_negative_labels = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 986, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 999, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12436,7 +12274,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("read_text", 0);
 
-  /* "pywrapfst.pyx":1005
+  /* "pywrapfst.pyx":1018
  *     """
  *     cdef unique_ptr[fst.SymbolTableTextOptions] opts
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
@@ -12445,16 +12283,16 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   __pyx_v_opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
 
-  /* "pywrapfst.pyx":1006
+  /* "pywrapfst.pyx":1019
  *     cdef unique_ptr[fst.SymbolTableTextOptions] opts
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.ReadText(tostring(filename),             # <<<<<<<<<<<<<<
  *                                                            deref(opts))
  *     if tsyms == NULL:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1006, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1019, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1007
+  /* "pywrapfst.pyx":1020
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.ReadText(tostring(filename),
  *                                                            deref(opts))             # <<<<<<<<<<<<<<
@@ -12463,7 +12301,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   __pyx_v_tsyms = fst::SymbolTable::ReadText(__pyx_t_1, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":1008
+  /* "pywrapfst.pyx":1021
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.ReadText(tostring(filename),
  *                                                            deref(opts))
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12473,16 +12311,16 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   __pyx_t_2 = ((__pyx_v_tsyms == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1009
+    /* "pywrapfst.pyx":1022
  *                                                            deref(opts))
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(tsyms)
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1022, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1009, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1022, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12495,13 +12333,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1022, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -12509,19 +12347,19 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12538,14 +12376,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1022, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -12554,20 +12392,20 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1022, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12575,9 +12413,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
     __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, 1009, __pyx_L1_error)
+    __PYX_ERR(0, 1022, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1008
+    /* "pywrapfst.pyx":1021
  *     cdef fst.SymbolTable *tsyms = fst.SymbolTable.ReadText(tostring(filename),
  *                                                            deref(opts))
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12586,7 +12424,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   }
 
-  /* "pywrapfst.pyx":1010
+  /* "pywrapfst.pyx":1023
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))
  *     return _init_SymbolTable(tsyms)             # <<<<<<<<<<<<<<
@@ -12594,13 +12432,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1010, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1023, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":986
+  /* "pywrapfst.pyx":999
  * 
  *   @classmethod
  *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12624,7 +12462,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1013
+/* "pywrapfst.pyx":1026
  * 
  *   @classmethod
  *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
@@ -12661,11 +12499,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_table)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1013, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1026, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1013, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1026, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -12674,11 +12512,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_filename = values[0];
-    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1013, __pyx_L3_error)
+    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1026, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1013, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1026, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12705,17 +12543,17 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("read_fst", 0);
 
-  /* "pywrapfst.pyx":1035
+  /* "pywrapfst.pyx":1048
  *     See also: `SymbolTable.read`, `SymbolTable.read_text`.
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.FstReadSymbols(filename, input_table)             # <<<<<<<<<<<<<<
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1035, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_filename); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1048, __pyx_L1_error)
   __pyx_v_tsyms = fst::FstReadSymbols(__pyx_t_1, __pyx_v_input_table);
 
-  /* "pywrapfst.pyx":1036
+  /* "pywrapfst.pyx":1049
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.FstReadSymbols(filename, input_table)
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12725,16 +12563,16 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   __pyx_t_2 = ((__pyx_v_tsyms == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1037
+    /* "pywrapfst.pyx":1050
  *     cdef fst.SymbolTable *tsyms = fst.FstReadSymbols(filename, input_table)
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *     return _init_SymbolTable(tsyms)
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1037, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1050, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1037, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1050, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -12747,13 +12585,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1037, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1050, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -12761,19 +12599,19 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12790,14 +12628,14 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1037, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -12806,20 +12644,20 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1037, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -12827,9 +12665,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
     __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, 1037, __pyx_L1_error)
+    __PYX_ERR(0, 1050, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1036
+    /* "pywrapfst.pyx":1049
  *     """
  *     cdef fst.SymbolTable *tsyms = fst.FstReadSymbols(filename, input_table)
  *     if tsyms == NULL:             # <<<<<<<<<<<<<<
@@ -12838,7 +12676,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
  */
   }
 
-  /* "pywrapfst.pyx":1038
+  /* "pywrapfst.pyx":1051
  *     if tsyms == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filename))
  *     return _init_SymbolTable(tsyms)             # <<<<<<<<<<<<<<
@@ -12846,13 +12684,13 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1038, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_tsyms)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1051, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1013
+  /* "pywrapfst.pyx":1026
  * 
  *   @classmethod
  *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
@@ -12876,7 +12714,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1041
+/* "pywrapfst.pyx":1054
  * 
  * 
  * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
@@ -12891,20 +12729,20 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1044
+  /* "pywrapfst.pyx":1057
  *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] encoder):
  *   cdef _EncodeMapperSymbolTable result = (
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))             # <<<<<<<<<<<<<<
  *   result._table = table
  *   result._encoder = encoder
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1044, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable)))) __PYX_ERR(0, 1044, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable)))) __PYX_ERR(0, 1057, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1045
+  /* "pywrapfst.pyx":1058
  *   cdef _EncodeMapperSymbolTable result = (
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -12913,11 +12751,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1045, __pyx_L1_error)
+    __PYX_ERR(0, 1058, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1046
+  /* "pywrapfst.pyx":1059
  *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
  *   result._table = table
  *   result._encoder = encoder             # <<<<<<<<<<<<<<
@@ -12926,23 +12764,23 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1046, __pyx_L1_error)
+    __PYX_ERR(0, 1059, __pyx_L1_error)
   }
   __pyx_v_result->_encoder = __pyx_v_encoder;
 
-  /* "pywrapfst.pyx":1047
+  /* "pywrapfst.pyx":1060
  *   result._table = table
  *   result._encoder = encoder
  *   return result             # <<<<<<<<<<<<<<
  * 
- * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
+ * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   __Pyx_INCREF(((PyObject *)__pyx_v_result));
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1041
+  /* "pywrapfst.pyx":1054
  * 
  * 
  * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
@@ -12962,8 +12800,8 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1049
- *   return result
+/* "pywrapfst.pyx":1063
+ * 
  * 
  * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
  *                                           shared_ptr[fst.FstClass] ifst):
@@ -12977,20 +12815,20 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_FstSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1051
+  /* "pywrapfst.pyx":1065
  * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
  *                                           shared_ptr[fst.FstClass] ifst):
  *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)             # <<<<<<<<<<<<<<
  *   result._table = table
  *   result._fst = ifst
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst__FstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1051, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst__FstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1065, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__FstSymbolTable)))) __PYX_ERR(0, 1051, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__FstSymbolTable)))) __PYX_ERR(0, 1065, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1052
+  /* "pywrapfst.pyx":1066
  *                                           shared_ptr[fst.FstClass] ifst):
  *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -12999,11 +12837,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1052, __pyx_L1_error)
+    __PYX_ERR(0, 1066, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1053
+  /* "pywrapfst.pyx":1067
  *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
  *   result._table = table
  *   result._fst = ifst             # <<<<<<<<<<<<<<
@@ -13012,11 +12850,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1053, __pyx_L1_error)
+    __PYX_ERR(0, 1067, __pyx_L1_error)
   }
   __pyx_v_result->_fst = __pyx_v_ifst;
 
-  /* "pywrapfst.pyx":1054
+  /* "pywrapfst.pyx":1068
  *   result._table = table
  *   result._fst = ifst
  *   return result             # <<<<<<<<<<<<<<
@@ -13028,8 +12866,8 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1049
- *   return result
+  /* "pywrapfst.pyx":1063
+ * 
  * 
  * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
  *                                           shared_ptr[fst.FstClass] ifst):
@@ -13048,7 +12886,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1057
+/* "pywrapfst.pyx":1071
  * 
  * 
  * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -13063,20 +12901,20 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFstSymbolTable", 0);
 
-  /* "pywrapfst.pyx":1060
+  /* "pywrapfst.pyx":1074
  *     shared_ptr[fst.MutableFstClass] ifst):
  *   cdef _MutableFstSymbolTable result = (
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))             # <<<<<<<<<<<<<<
  *   result._table = table
  *   result._mfst = ifst
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst__MutableFstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst__MutableFstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1074, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__MutableFstSymbolTable)))) __PYX_ERR(0, 1060, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst__MutableFstSymbolTable)))) __PYX_ERR(0, 1074, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1061
+  /* "pywrapfst.pyx":1075
  *   cdef _MutableFstSymbolTable result = (
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -13085,11 +12923,11 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1061, __pyx_L1_error)
+    __PYX_ERR(0, 1075, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1062
+  /* "pywrapfst.pyx":1076
  *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
  *   result._table = table
  *   result._mfst = ifst             # <<<<<<<<<<<<<<
@@ -13098,11 +12936,11 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 1062, __pyx_L1_error)
+    __PYX_ERR(0, 1076, __pyx_L1_error)
   }
   __pyx_v_result->_mfst = __pyx_v_ifst;
 
-  /* "pywrapfst.pyx":1063
+  /* "pywrapfst.pyx":1077
  *   result._table = table
  *   result._mfst = ifst
  *   return result             # <<<<<<<<<<<<<<
@@ -13114,7 +12952,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1057
+  /* "pywrapfst.pyx":1071
  * 
  * 
  * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
@@ -13134,7 +12972,7 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1066
+/* "pywrapfst.pyx":1080
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
@@ -13149,20 +12987,20 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_SymbolTable", 0);
 
-  /* "pywrapfst.pyx":1067
+  /* "pywrapfst.pyx":1081
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
  *   result._table = table
  *   return result
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1067, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1081, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_SymbolTable)))) __PYX_ERR(0, 1067, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_SymbolTable)))) __PYX_ERR(0, 1081, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1068
+  /* "pywrapfst.pyx":1082
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
  *   result._table = table             # <<<<<<<<<<<<<<
@@ -13171,11 +13009,11 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1068, __pyx_L1_error)
+    __PYX_ERR(0, 1082, __pyx_L1_error)
   }
   __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
 
-  /* "pywrapfst.pyx":1069
+  /* "pywrapfst.pyx":1083
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
  *   result._table = table
  *   return result             # <<<<<<<<<<<<<<
@@ -13187,7 +13025,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1066
+  /* "pywrapfst.pyx":1080
  * 
  * 
  * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
@@ -13207,7 +13045,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1075
+/* "pywrapfst.pyx":1089
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13222,7 +13060,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1087
+  /* "pywrapfst.pyx":1101
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(fst.CompactSymbolTable(deref(syms._table)))             # <<<<<<<<<<<<<<
@@ -13232,15 +13070,15 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1087, __pyx_L1_error)
+    __PYX_ERR(0, 1101, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::CompactSymbolTable((*__pyx_v_syms->_table)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1087, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::CompactSymbolTable((*__pyx_v_syms->_table)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1101, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1075
+  /* "pywrapfst.pyx":1089
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13266,7 +13104,7 @@ static PyObject *__pyx_pw_9pywrapfst_9compact_symbol_table(PyObject *__pyx_self,
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compact_symbol_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1075, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1089, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_8compact_symbol_table(__pyx_self, ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -13284,7 +13122,7 @@ static PyObject *__pyx_pf_9pywrapfst_8compact_symbol_table(CYTHON_UNUSED PyObjec
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_syms, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1075, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_syms, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1089, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13301,7 +13139,7 @@ static PyObject *__pyx_pf_9pywrapfst_8compact_symbol_table(CYTHON_UNUSED PyObjec
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1090
+/* "pywrapfst.pyx":1104
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13316,7 +13154,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1114
+  /* "pywrapfst.pyx":1128
  *   See also: `relabel_symbols`.
  *   """
  *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),             # <<<<<<<<<<<<<<
@@ -13326,10 +13164,10 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1114, __pyx_L1_error)
+    __PYX_ERR(0, 1128, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1115
+  /* "pywrapfst.pyx":1129
  *   """
  *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),
  *                                                 deref(rhs._table), NULL))             # <<<<<<<<<<<<<<
@@ -13338,23 +13176,23 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1115, __pyx_L1_error)
+    __PYX_ERR(0, 1129, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1114
+  /* "pywrapfst.pyx":1128
  *   See also: `relabel_symbols`.
  *   """
  *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),             # <<<<<<<<<<<<<<
  *                                                 deref(rhs._table), NULL))
  * 
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::MergeSymbolTable((*__pyx_v_lhs->_table), (*__pyx_v_rhs->_table), NULL))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1114, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::MergeSymbolTable((*__pyx_v_lhs->_table), (*__pyx_v_rhs->_table), NULL))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1128, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1090
+  /* "pywrapfst.pyx":1104
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13402,11 +13240,11 @@ static PyObject *__pyx_pw_9pywrapfst_11merge_symbol_table(PyObject *__pyx_self,
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1090, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1104, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1090, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1104, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -13419,14 +13257,14 @@ static PyObject *__pyx_pw_9pywrapfst_11merge_symbol_table(PyObject *__pyx_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1090, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1104, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.merge_symbol_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "lhs", 0))) __PYX_ERR(0, 1090, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1090, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "lhs", 0))) __PYX_ERR(0, 1104, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1104, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10merge_symbol_table(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -13444,7 +13282,7 @@ static PyObject *__pyx_pf_9pywrapfst_10merge_symbol_table(CYTHON_UNUSED PyObject
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1090, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1104, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13461,7 +13299,7 @@ static PyObject *__pyx_pf_9pywrapfst_10merge_symbol_table(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1132
+/* "pywrapfst.pyx":1143
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -13492,7 +13330,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1133
+  /* "pywrapfst.pyx":1144
  * 
  *   def __repr__(self):
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -13500,14 +13338,14 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
  *   def __init__(self, _SymbolTable syms):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_SymbolTableIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1133, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_SymbolTableIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1133, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1133, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -13521,14 +13359,14 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1133, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1133, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -13537,20 +13375,20 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1133, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1133, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1144, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1133, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1144, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -13560,7 +13398,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1132
+  /* "pywrapfst.pyx":1143
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -13583,7 +13421,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1135
+/* "pywrapfst.pyx":1146
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13616,7 +13454,7 @@ static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1135, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1146, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -13627,13 +13465,13 @@ static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1135, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1146, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1135, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1146, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self), __pyx_v_syms);
 
   /* function exit code */
@@ -13650,7 +13488,7 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1136
+  /* "pywrapfst.pyx":1147
  * 
  *   def __init__(self, _SymbolTable syms):
  *     self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))             # <<<<<<<<<<<<<<
@@ -13659,15 +13497,15 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1136, __pyx_L1_error)
+    __PYX_ERR(0, 1147, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1136, __pyx_L1_error)
+    __PYX_ERR(0, 1147, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::SymbolTableIterator((*__pyx_v_syms->_table)));
 
-  /* "pywrapfst.pyx":1135
+  /* "pywrapfst.pyx":1146
  *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13686,7 +13524,7 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1139
+/* "pywrapfst.pyx":1150
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13712,7 +13550,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":1140
+  /* "pywrapfst.pyx":1151
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -13724,7 +13562,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1139
+  /* "pywrapfst.pyx":1150
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13739,7 +13577,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1143
+/* "pywrapfst.pyx":1154
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -13771,7 +13609,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":1144
+  /* "pywrapfst.pyx":1155
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -13780,12 +13618,12 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "done");
-    __PYX_ERR(0, 1144, __pyx_L1_error)
+    __PYX_ERR(0, 1155, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1145
+    /* "pywrapfst.pyx":1156
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -13793,9 +13631,9 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  *     cdef string symbol = self.symbol()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 1145, __pyx_L1_error)
+    __PYX_ERR(0, 1156, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1144
+    /* "pywrapfst.pyx":1155
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -13804,7 +13642,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   }
 
-  /* "pywrapfst.pyx":1146
+  /* "pywrapfst.pyx":1157
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 value = self.value()             # <<<<<<<<<<<<<<
@@ -13813,11 +13651,11 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "value");
-    __PYX_ERR(0, 1146, __pyx_L1_error)
+    __PYX_ERR(0, 1157, __pyx_L1_error)
   }
   __pyx_v_value = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1147
+  /* "pywrapfst.pyx":1158
  *       raise StopIteration
  *     cdef int64 value = self.value()
  *     cdef string symbol = self.symbol()             # <<<<<<<<<<<<<<
@@ -13826,11 +13664,11 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "symbol");
-    __PYX_ERR(0, 1147, __pyx_L1_error)
+    __PYX_ERR(0, 1158, __pyx_L1_error)
   }
   __pyx_v_symbol = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->symbol(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1148
+  /* "pywrapfst.pyx":1159
  *     cdef int64 value = self.value()
  *     cdef string symbol = self.symbol()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -13839,11 +13677,11 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "next");
-    __PYX_ERR(0, 1148, __pyx_L1_error)
+    __PYX_ERR(0, 1159, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":1149
+  /* "pywrapfst.pyx":1160
  *     cdef string symbol = self.symbol()
  *     self.next()
  *     return (value, symbol)             # <<<<<<<<<<<<<<
@@ -13851,11 +13689,11 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
  *   cpdef bool done(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1149, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1160, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1149, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1160, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1149, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1160, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
@@ -13867,7 +13705,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1143
+  /* "pywrapfst.pyx":1154
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -13888,7 +13726,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1151
+/* "pywrapfst.pyx":1162
  *     return (value, symbol)
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -13910,7 +13748,7 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1151, __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, 1162, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_9done)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -13925,14 +13763,14 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1151, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1162, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1151, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1162, __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, 1151, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1162, __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;
@@ -13941,7 +13779,7 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1163
+  /* "pywrapfst.pyx":1171
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -13950,12 +13788,12 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1163, __pyx_L1_error)
+    __PYX_ERR(0, 1171, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1151
+  /* "pywrapfst.pyx":1162
  *     return (value, symbol)
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -13978,7 +13816,7 @@ static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static char __pyx_doc_9pywrapfst_19SymbolTableIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -13996,7 +13834,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_8done(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_19SymbolTableIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1151, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_19SymbolTableIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1162, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14013,7 +13851,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_8done(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1165
+/* "pywrapfst.pyx":1173
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -14033,7 +13871,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1165, __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, 1173, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_11next)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -14048,10 +13886,10 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1165, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1173, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1165, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1173, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -14062,8 +13900,8 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1174
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":1179
+ *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
  * 
@@ -14071,11 +13909,11 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1174, __pyx_L1_error)
+    __PYX_ERR(0, 1179, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":1165
+  /* "pywrapfst.pyx":1173
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -14097,7 +13935,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_19SymbolTableIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -14115,7 +13953,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_10next(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1165, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1173, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14132,7 +13970,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_10next(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1176
+/* "pywrapfst.pyx":1181
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -14152,7 +13990,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1176, __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, 1181, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -14167,10 +14005,10 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1176, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1181, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1176, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1181, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -14181,8 +14019,8 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1185
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":1187
+ *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
  * 
@@ -14190,11 +14028,11 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1185, __pyx_L1_error)
+    __PYX_ERR(0, 1187, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":1176
+  /* "pywrapfst.pyx":1181
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -14216,7 +14054,7 @@ static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pyw
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_19SymbolTableIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -14234,7 +14072,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(struct __pyx_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1176, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1181, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14251,7 +14089,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1187
+/* "pywrapfst.pyx":1189
  *     self._siter.get().Reset()
  * 
  *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
@@ -14273,7 +14111,7 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1187, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1189, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -14288,14 +14126,14 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1187, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1189, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1187, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1189, __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, 1187, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1189, __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;
@@ -14304,7 +14142,7 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1201
+  /* "pywrapfst.pyx":1200
  *       A symbol string.
  *     """
  *     return self._siter.get().Symbol()             # <<<<<<<<<<<<<<
@@ -14313,12 +14151,12 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1201, __pyx_L1_error)
+    __PYX_ERR(0, 1200, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Symbol();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1187
+  /* "pywrapfst.pyx":1189
  *     self._siter.get().Reset()
  * 
  *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
@@ -14340,7 +14178,7 @@ static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_14symbol[] = "\n    symbol(self)\n\n    Returns the current symbol string.\n\n    This method returns the current symbol string at this point in the table.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      A symbol string.\n    ";
+static char __pyx_doc_9pywrapfst_19SymbolTableIterator_14symbol[] = "\n    symbol(self)\n\n    Returns the current symbol string.\n\n    This method returns the current symbol string at this point in the table.\n\n    Returns:\n      A symbol string.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -14358,7 +14196,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(struct __pyx
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("symbol", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_19SymbolTableIterator_symbol(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1187, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_19SymbolTableIterator_symbol(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1189, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14375,7 +14213,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1203
+/* "pywrapfst.pyx":1202
  *     return self._siter.get().Symbol()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -14397,7 +14235,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1203, __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, 1202, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_17value)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -14412,14 +14250,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1203, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1202, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1203, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1202, __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, 1203, __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, 1202, __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;
@@ -14428,7 +14266,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1215
+  /* "pywrapfst.pyx":1211
  *       An integer index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -14437,12 +14275,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_siter");
-    __PYX_ERR(0, 1215, __pyx_L1_error)
+    __PYX_ERR(0, 1211, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1203
+  /* "pywrapfst.pyx":1202
  *     return self._siter.get().Symbol()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -14465,7 +14303,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_17value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_16value[] = "\n    value(self)\n\n    Returns the current integer index of the symbol.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      An integer index.\n    ";
+static char __pyx_doc_9pywrapfst_19SymbolTableIterator_16value[] = "\n    value(self)\n\n    Returns the current integer index of the symbol.\n\n    Returns:\n      An integer index.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_17value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -14483,7 +14321,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_16value(struct __pyx_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_19SymbolTableIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1203, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_19SymbolTableIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1202, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -14500,7 +14338,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_16value(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1244
+/* "pywrapfst.pyx":1240
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14531,7 +14369,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1245
+  /* "pywrapfst.pyx":1241
  * 
  *   def __repr__(self):
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -14539,14 +14377,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
  *   def __init__(self,
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_EncodeMapper_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1245, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_EncodeMapper_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1241, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1241, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1241, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -14560,14 +14398,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1241, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1241, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -14576,20 +14414,20 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1241, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1245, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1241, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1241, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -14599,7 +14437,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1244
+  /* "pywrapfst.pyx":1240
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14622,7 +14460,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1247
+/* "pywrapfst.pyx":1243
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14672,7 +14510,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1247, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1243, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -14685,10 +14523,10 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
     }
     __pyx_v_arc_type = values[0];
     if (values[1]) {
-      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1249, __pyx_L3_error)
+      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1245, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1249
+      /* "pywrapfst.pyx":1245
  *   def __init__(self,
  *                arc_type=b"standard",
  *                bool encode_labels=False,             # <<<<<<<<<<<<<<
@@ -14698,10 +14536,10 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
       __pyx_v_encode_labels = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1250, __pyx_L3_error)
+      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1246, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1250
+      /* "pywrapfst.pyx":1246
  *                arc_type=b"standard",
  *                bool encode_labels=False,
  *                bool encode_weights=False):             # <<<<<<<<<<<<<<
@@ -14713,7 +14551,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1247, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1243, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14721,7 +14559,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc_type, __pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1247
+  /* "pywrapfst.pyx":1243
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14748,7 +14586,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1251
+  /* "pywrapfst.pyx":1247
  *                bool encode_labels=False,
  *                bool encode_weights=False):
  *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
@@ -14757,7 +14595,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   __pyx_v_flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1252
+  /* "pywrapfst.pyx":1248
  *                bool encode_weights=False):
  *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,             # <<<<<<<<<<<<<<
@@ -14766,11 +14604,11 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1252, __pyx_L1_error)
+    __PYX_ERR(0, 1248, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1252, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1248, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1253
+  /* "pywrapfst.pyx":1249
  *     cdef uint32 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))             # <<<<<<<<<<<<<<
@@ -14779,7 +14617,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   __pyx_v_self->_encoder.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v_flags, fst::ENCODE));
 
-  /* "pywrapfst.pyx":1254
+  /* "pywrapfst.pyx":1250
  *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))
  *     if not self._encoder:             # <<<<<<<<<<<<<<
@@ -14788,21 +14626,21 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1254, __pyx_L1_error)
+    __PYX_ERR(0, 1250, __pyx_L1_error)
   }
   __pyx_t_2 = ((!__pyx_v_self->_encoder) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1255
+    /* "pywrapfst.pyx":1251
  *                                                   fst.ENCODE))
  *     if not self._encoder:
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1255, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1251, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1255, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1251, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -14815,13 +14653,13 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1251, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_arc_type};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -14829,19 +14667,19 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_arc_type};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_arc_type);
         __Pyx_GIVEREF(__pyx_v_arc_type);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_arc_type);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -14858,14 +14696,14 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1251, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -14874,20 +14712,20 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1255, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1251, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -14895,9 +14733,9 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     __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, 1255, __pyx_L1_error)
+    __PYX_ERR(0, 1251, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1254
+    /* "pywrapfst.pyx":1250
  *     self._encoder.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
  *                                                   fst.ENCODE))
  *     if not self._encoder:             # <<<<<<<<<<<<<<
@@ -14906,7 +14744,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1247
+  /* "pywrapfst.pyx":1243
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14931,12 +14769,12 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1257
+/* "pywrapfst.pyx":1253
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -14953,7 +14791,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1257, __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, 1253, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -14968,14 +14806,14 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1257, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1253, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1257, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1253, __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, 1257, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1253, __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;
@@ -14984,26 +14822,26 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1258
- * 
- *   cpdef string arc_type(self):
+  /* "pywrapfst.pyx":1259
+ *     Returns a string indicating the arc type.
+ *     """
  *     return self._encoder.get().ArcType()             # <<<<<<<<<<<<<<
  * 
  *   # Python's equivalent to operator().
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1258, __pyx_L1_error)
+    __PYX_ERR(0, 1259, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_encoder.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1257
+  /* "pywrapfst.pyx":1253
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
   /* function exit code */
@@ -15020,6 +14858,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_4arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -15037,7 +14876,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1257, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1253, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15054,7 +14893,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4arc_type(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1262
+/* "pywrapfst.pyx":1263
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -15091,7 +14930,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__call__(PyObject *__pyx_v_
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1262, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1263, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -15102,13 +14941,13 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_7__call__(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1262, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1263, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1262, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1263, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_6__call__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc);
 
   /* function exit code */
@@ -15126,7 +14965,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__call__", 0);
 
-  /* "pywrapfst.pyx":1278
+  /* "pywrapfst.pyx":1279
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
@@ -15136,19 +14975,19 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1278, __pyx_L1_error)
+    __PYX_ERR(0, 1279, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc");
-    __PYX_ERR(0, 1278, __pyx_L1_error)
+    __PYX_ERR(0, 1279, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_encoder.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_encoder.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1279, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1262
+  /* "pywrapfst.pyx":1263
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -15167,12 +15006,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__call__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1280
+/* "pywrapfst.pyx":1281
  *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().Flags()
- * 
+ *     """
+ *     flags(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -15189,7 +15028,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1280, __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, 1281, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_9flags)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -15204,14 +15043,14 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1280, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1281, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1280, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1281, __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, 1280, __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, 1281, __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;
@@ -15220,26 +15059,26 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1281
- * 
- *   cpdef uint32 flags(self):
+  /* "pywrapfst.pyx":1287
+ *     Returns the encoder's flags.
+ *     """
  *     return self._encoder.get().Flags()             # <<<<<<<<<<<<<<
  * 
  *   cpdef _EncodeMapperSymbolTable input_symbols(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1281, __pyx_L1_error)
+    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_encoder.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1280
+  /* "pywrapfst.pyx":1281
  *     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().Flags()
- * 
+ *     """
+ *     flags(self)
  */
 
   /* function exit code */
@@ -15257,6 +15096,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_12EncodeMapper_flags(struc
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_8flags[] = "\n    flags(self)\n\n    Returns the encoder's flags.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_9flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -15274,7 +15114,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(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_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint32_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1281, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15291,16 +15131,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1283
+/* "pywrapfst.pyx":1289
  *     return self._encoder.get().Flags()
  * 
  *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._encoder.get().InputSymbols() == NULL:
- *       return
+ *     """
+ *     input_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  fst::SymbolTable *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -15313,7 +15154,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1283, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1289, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -15329,14 +15170,14 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1283, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1289, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1283, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1289, __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__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1283, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1289, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15345,92 +15186,81 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1284
- * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):
- *     if self._encoder.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1296
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().InputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1284, __pyx_L1_error)
+    __PYX_ERR(0, 1296, __pyx_L1_error)
   }
-  __pyx_t_5 = ((__pyx_v_self->_encoder.get()->InputSymbols() == NULL) != 0);
-  if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1285
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):
- *     if self._encoder.get().InputSymbols() == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols()), self._encoder)
+  /* "pywrapfst.pyx":1295
+ *     Returns the encoder's input symbol table, or None if none is present.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *         self._encoder.get().InputSymbols())
+ *     if syms == NULL:
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->InputSymbols());
 
-    /* "pywrapfst.pyx":1284
- * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):
- *     if self._encoder.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1297
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  */
-  }
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
 
-  /* "pywrapfst.pyx":1286
- *     if self._encoder.get().InputSymbols() == NULL:
- *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._encoder.get().InputSymbols()), self._encoder)
+    /* "pywrapfst.pyx":1298
+ *         self._encoder.get().InputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  */
-  __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1287
+    /* "pywrapfst.pyx":1297
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols()), self._encoder)             # <<<<<<<<<<<<<<
- * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1286
- *     if self._encoder.get().InputSymbols() == NULL:
+  /* "pywrapfst.pyx":1299
+ *     if syms == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._encoder.get().InputSymbols()), self._encoder)
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)             # <<<<<<<<<<<<<<
  * 
+ *   cpdef _EncodeMapperSymbolTable output_symbols(self):
  */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1287, __pyx_L1_error)
+    __PYX_ERR(0, 1299, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1287
- *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().InputSymbols()), self._encoder)             # <<<<<<<<<<<<<<
- * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
- */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->InputSymbols()), __pyx_v_self->_encoder)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1286, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_encoder)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1299, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1283
+  /* "pywrapfst.pyx":1289
  *     return self._encoder.get().Flags()
  * 
  *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._encoder.get().InputSymbols() == NULL:
- *       return
+ *     """
+ *     input_symbols(self)
  */
 
   /* function exit code */
@@ -15449,6 +15279,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_10input_symbols[] = "\n    input_symbols(self)\n\n    Returns the encoder's input symbol table, or None if none is present.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -15466,7 +15297,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1283, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15483,16 +15314,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10input_symbols(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1289
- *         self._encoder.get().InputSymbols()), self._encoder)
+/* "pywrapfst.pyx":1301
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._encoder.get().OutputSymbols() == NULL:
- *       return
+ *     """
+ *     output_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  fst::SymbolTable *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -15505,7 +15337,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1289, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1301, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -15521,14 +15353,14 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1289, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1301, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1289, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1301, __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__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1289, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1301, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15537,92 +15369,81 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1290
- * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
- *     if self._encoder.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1308
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().OutputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1290, __pyx_L1_error)
+    __PYX_ERR(0, 1308, __pyx_L1_error)
   }
-  __pyx_t_5 = ((__pyx_v_self->_encoder.get()->OutputSymbols() == NULL) != 0);
-  if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1291
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
- *     if self._encoder.get().OutputSymbols() == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols()), self._encoder)
+  /* "pywrapfst.pyx":1307
+ *     Returns the encoder's output symbol table, or None if none is present.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *         self._encoder.get().OutputSymbols())
+ *     if syms == NULL:
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->OutputSymbols());
 
-    /* "pywrapfst.pyx":1290
- * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
- *     if self._encoder.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1309
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  */
-  }
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
 
-  /* "pywrapfst.pyx":1292
- *     if self._encoder.get().OutputSymbols() == NULL:
- *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._encoder.get().OutputSymbols()), self._encoder)
+    /* "pywrapfst.pyx":1310
+ *         self._encoder.get().OutputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  */
-  __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1293
+    /* "pywrapfst.pyx":1309
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *         self._encoder.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols()), self._encoder)             # <<<<<<<<<<<<<<
- * 
- *   cpdef uint64 properties(self, uint64 mask):
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1293, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1292
- *     if self._encoder.get().OutputSymbols() == NULL:
+  /* "pywrapfst.pyx":1311
+ *     if syms == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._encoder.get().OutputSymbols()), self._encoder)
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)             # <<<<<<<<<<<<<<
  * 
+ *   cpdef uint64 properties(self, uint64 mask):
  */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1293, __pyx_L1_error)
+    __PYX_ERR(0, 1311, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1293
- *       return
- *     return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
- *         self._encoder.get().OutputSymbols()), self._encoder)             # <<<<<<<<<<<<<<
- * 
- *   cpdef uint64 properties(self, uint64 mask):
- */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_encoder.get()->OutputSymbols()), __pyx_v_self->_encoder)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1292, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_encoder)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1311, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1289
- *         self._encoder.get().InputSymbols()), self._encoder)
+  /* "pywrapfst.pyx":1301
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._encoder.get().OutputSymbols() == NULL:
- *       return
+ *     """
+ *     output_symbols(self)
  */
 
   /* function exit code */
@@ -15641,6 +15462,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_12output_symbols[] = "\n    output_symbols(self)\n\n    Returns the encoder's output symbol table, or None if none is present.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -15658,7 +15480,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1289, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1301, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15675,8 +15497,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12output_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1295
- *         self._encoder.get().OutputSymbols()), self._encoder)
+/* "pywrapfst.pyx":1313
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
@@ -15699,10 +15521,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1295, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1313, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_15properties)) {
-      __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1295, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1313, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -15716,14 +15538,14 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1295, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1295, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -15732,26 +15554,26 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1295, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1295, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1313, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1295, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_7 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_7 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1295, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_7 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1313, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_7;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15760,7 +15582,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1311
+  /* "pywrapfst.pyx":1327
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._encoder.get().Properties(mask)             # <<<<<<<<<<<<<<
@@ -15769,13 +15591,13 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1311, __pyx_L1_error)
+    __PYX_ERR(0, 1327, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_encoder.get()->Properties(__pyx_v_mask);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1295
- *         self._encoder.get().OutputSymbols()), self._encoder)
+  /* "pywrapfst.pyx":1313
+ *     return _init_EncodeMapperSymbolTable(syms, self._encoder)
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
@@ -15799,14 +15621,14 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx_v_self, PyObject *__pyx_arg_mask); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_14properties[] = "\n    properties(self, mask)\n\n    Provides property bits.\n\n    This method provides user access to the properties attributes for the\n    encoder. The resulting value is a long integer, but when it is cast to a\n    boolean, it represents whether or not the FST has the `mask` property.\n\n    Args:\n      mask: The property mask to be compared to the encoder's properties.\n\n    Returns:\n      A 64-bit bitmask representing the requested properties.\n    ";
+static char __pyx_doc_9pywrapfst_12EncodeMapper_14properties[] = "\n    properties(self, mask)\n\n    Provides property bits.\n\n    This method provides user access to the properties of the encoder.\n\n    Args:\n      mask: The property mask to be compared to the encoder's properties.\n\n    Returns:\n      A 64-bit bitmask representing the requested properties.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx_v_self, PyObject *__pyx_arg_mask) {
   __pyx_t_10basictypes_uint64 __pyx_v_mask;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("properties (wrapper)", 0);
   assert(__pyx_arg_mask); {
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(__pyx_arg_mask); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1295, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(__pyx_arg_mask); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1313, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -15827,7 +15649,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("properties", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_12EncodeMapper_properties(__pyx_v_self, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1295, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_12EncodeMapper_properties(__pyx_v_self, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1313, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15844,7 +15666,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1313
+/* "pywrapfst.pyx":1329
  *     return self._encoder.get().Properties(mask)
  * 
  *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -15865,7 +15687,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1313, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1329, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_17set_input_symbols)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -15880,13 +15702,13 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -15894,19 +15716,19 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1313, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1329, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(((PyObject *)__pyx_v_syms));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_syms));
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, ((PyObject *)__pyx_v_syms));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1329, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -15919,7 +15741,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1324
+  /* "pywrapfst.pyx":1340
  *     See also: `set_output_symbols`.
  *     """
  *     self._encoder.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -15928,15 +15750,15 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1324, __pyx_L1_error)
+    __PYX_ERR(0, 1340, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1324, __pyx_L1_error)
+    __PYX_ERR(0, 1340, __pyx_L1_error)
   }
   __pyx_v_self->_encoder.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":1313
+  /* "pywrapfst.pyx":1329
  *     return self._encoder.get().Properties(mask)
  * 
  *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -15959,12 +15781,12 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(struct __pyx_obj
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_16set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    See also: `set_output_symbols`.\n    ";
+static char __pyx_doc_9pywrapfst_12EncodeMapper_16set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the encoder's input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    See also: `set_output_symbols`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17set_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, 1313, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1329, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -15982,8 +15804,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct _
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1313, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1313, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1329, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1329, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16000,7 +15822,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16set_input_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1326
+/* "pywrapfst.pyx":1342
  *     self._encoder.get().SetInputSymbols(syms._table)
  * 
  *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -16021,7 +15843,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1342, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -16036,13 +15858,13 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1342, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1342, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -16050,19 +15872,19 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_syms)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1342, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1326, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1342, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(((PyObject *)__pyx_v_syms));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_syms));
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, ((PyObject *)__pyx_v_syms));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1342, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -16075,7 +15897,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1337
+  /* "pywrapfst.pyx":1353
  *     See also: `set_input_symbols`.
  *     """
  *     self._encoder.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
@@ -16084,15 +15906,15 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1337, __pyx_L1_error)
+    __PYX_ERR(0, 1353, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 1337, __pyx_L1_error)
+    __PYX_ERR(0, 1353, __pyx_L1_error)
   }
   __pyx_v_self->_encoder.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":1326
+  /* "pywrapfst.pyx":1342
  *     self._encoder.get().SetInputSymbols(syms._table)
  * 
  *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -16115,12 +15937,12 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(struct __pyx_ob
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_18set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    See also: `set_input_symbols`.\n    ";
+static char __pyx_doc_9pywrapfst_12EncodeMapper_18set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the encoder's output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    See also: `set_input_symbols`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19set_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, 1326, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1342, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
 
   /* function exit code */
@@ -16138,8 +15960,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1326, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1342, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1342, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16156,12 +15978,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18set_output_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1339
+/* "pywrapfst.pyx":1355
  *     self._encoder.get().SetOutputSymbols(syms._table)
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().WeightType()
- * 
+ *     """
+ *     weight_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -16178,7 +16000,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1339, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1355, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -16193,14 +16015,14 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1339, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1339, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1355, __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, 1339, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1355, __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;
@@ -16209,26 +16031,26 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1340
- * 
- *   cpdef string weight_type(self):
+  /* "pywrapfst.pyx":1361
+ *     Returns a string indicating the weight type.
+ *     """
  *     return self._encoder.get().WeightType()             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1340, __pyx_L1_error)
+    __PYX_ERR(0, 1361, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_encoder.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1339
+  /* "pywrapfst.pyx":1355
  *     self._encoder.get().SetOutputSymbols(syms._table)
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
- *     return self._encoder.get().WeightType()
- * 
+ *     """
+ *     weight_type(self)
  */
 
   /* function exit code */
@@ -16245,6 +16067,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_20weight_type[] = "\n    weight_type(self)\n\n    Returns a string indicating the weight type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -16262,7 +16085,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1339, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1355, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16279,7 +16102,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20weight_type(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1364
+/* "pywrapfst.pyx":1385
  * 
  *   # IPython notebook magic to produce an SVG of the FST.
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -16322,19 +16145,19 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_12 = NULL;
   __Pyx_RefNannySetupContext("_repr_svg_", 0);
 
-  /* "pywrapfst.pyx":1378
+  /* "pywrapfst.pyx":1399
  *     """
  *     # Throws OSError if the dot executable is not found.
  *     proc = subprocess.Popen(["dot", "-Tsvg"], stdin=subprocess.PIPE,             # <<<<<<<<<<<<<<
  *                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  *     cdef stringstream sstrm
  */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_n_s_dot);
   __Pyx_GIVEREF(__pyx_n_s_dot);
@@ -16342,51 +16165,51 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   __Pyx_INCREF(__pyx_kp_s_Tsvg);
   __Pyx_GIVEREF(__pyx_kp_s_Tsvg);
   PyList_SET_ITEM(__pyx_t_1, 1, __pyx_kp_s_Tsvg);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_5) < 0) __PYX_ERR(0, 1378, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_5) < 0) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "pywrapfst.pyx":1379
+  /* "pywrapfst.pyx":1400
  *     # Throws OSError if the dot executable is not found.
  *     proc = subprocess.Popen(["dot", "-Tsvg"], stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)             # <<<<<<<<<<<<<<
  *     cdef stringstream sstrm
  *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
  */
-  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1379, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1400, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1379, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1400, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_4) < 0) __PYX_ERR(0, 1378, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_4) < 0) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1379, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1400, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1379, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1400, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stderr, __pyx_t_5) < 0) __PYX_ERR(0, 1378, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stderr, __pyx_t_5) < 0) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "pywrapfst.pyx":1378
+  /* "pywrapfst.pyx":1399
  *     """
  *     # Throws OSError if the dot executable is not found.
  *     proc = subprocess.Popen(["dot", "-Tsvg"], stdin=subprocess.PIPE,             # <<<<<<<<<<<<<<
  *                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  *     cdef stringstream sstrm
  */
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1378, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -16394,7 +16217,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   __pyx_v_proc = __pyx_t_5;
   __pyx_t_5 = 0;
 
-  /* "pywrapfst.pyx":1381
+  /* "pywrapfst.pyx":1402
  *                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  *     cdef stringstream sstrm
  *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
@@ -16403,14 +16226,14 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1381, __pyx_L1_error)
+    __PYX_ERR(0, 1402, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1381, __pyx_L1_error)
+    __PYX_ERR(0, 1402, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1382
+  /* "pywrapfst.pyx":1403
  *     cdef stringstream sstrm
  *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
  *                 self._fst.get().OutputSymbols(), NULL,             # <<<<<<<<<<<<<<
@@ -16419,10 +16242,10 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1382, __pyx_L1_error)
+    __PYX_ERR(0, 1403, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1383
+  /* "pywrapfst.pyx":1404
  *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),
  *                 self._fst.get().OutputSymbols(), NULL,
  *                 self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
@@ -16431,29 +16254,29 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1383, __pyx_L1_error)
+    __PYX_ERR(0, 1404, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1385
+  /* "pywrapfst.pyx":1406
  *                 self._fst.get().Properties(fst.kAcceptor, True) ==
  *                 fst.kAcceptor,
  *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,             # <<<<<<<<<<<<<<
  *                 addr(sstrm), b"_repr_svg")
  *     (sout, serr) = proc.communicate(sstrm.str())
  */
-  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1385, __pyx_L1_error)
-  __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_g); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1385, __pyx_L1_error)
+  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b__5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1406, __pyx_L1_error)
+  __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_g); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1406, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1386
+  /* "pywrapfst.pyx":1407
  *                 fst.kAcceptor,
  *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
  *                 addr(sstrm), b"_repr_svg")             # <<<<<<<<<<<<<<
  *     (sout, serr) = proc.communicate(sstrm.str())
  *     if proc.returncode != 0:  # Just to be explicit.
  */
-  __pyx_t_8 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_repr_svg); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1386, __pyx_L1_error)
+  __pyx_t_8 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_repr_svg); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1407, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1381
+  /* "pywrapfst.pyx":1402
  *                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  *     cdef stringstream sstrm
  *     fst.DrawFst(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
@@ -16462,16 +16285,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   fst::script::DrawFst((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, (__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor), __pyx_t_6, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_t_7, 0, (&__pyx_v_sstrm), __pyx_t_8);
 
-  /* "pywrapfst.pyx":1387
+  /* "pywrapfst.pyx":1408
  *                 b"", 8.5, 11, True, False, 0.4, 0.25, 14, 5, b"g", False,
  *                 addr(sstrm), b"_repr_svg")
  *     (sout, serr) = proc.communicate(sstrm.str())             # <<<<<<<<<<<<<<
  *     if proc.returncode != 0:  # Just to be explicit.
  *       raise subprocess.CalledProcessError(proc.returncode, self._DOT_TSVG)
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1387, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1408, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1387, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1408, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_2 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
@@ -16484,14 +16307,14 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     }
   }
   if (!__pyx_t_2) {
-    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1387, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1408, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_5);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_1)) {
       PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_t_3};
-      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1387, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1408, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -16500,20 +16323,20 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
       PyObject *__pyx_temp[2] = {__pyx_t_2, __pyx_t_3};
-      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1387, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1408, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1387, __pyx_L1_error)
+      __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1408, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __pyx_t_2 = NULL;
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1387, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1408, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     }
@@ -16529,7 +16352,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     if (unlikely(size != 2)) {
       if (size > 2) __Pyx_RaiseTooManyValuesError(2);
       else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-      __PYX_ERR(0, 1387, __pyx_L1_error)
+      __PYX_ERR(0, 1408, __pyx_L1_error)
     }
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
     if (likely(PyTuple_CheckExact(sequence))) {
@@ -16542,15 +16365,15 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_INCREF(__pyx_t_1);
     __Pyx_INCREF(__pyx_t_4);
     #else
-    __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1387, __pyx_L1_error)
+    __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1408, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1387, __pyx_L1_error)
+    __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1408, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     #endif
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   } else {
     Py_ssize_t index = -1;
-    __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1387, __pyx_L1_error)
+    __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1408, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext;
@@ -16558,7 +16381,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_GOTREF(__pyx_t_1);
     index = 1; __pyx_t_4 = __pyx_t_9(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed;
     __Pyx_GOTREF(__pyx_t_4);
-    if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1387, __pyx_L1_error)
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_3), 2) < 0) __PYX_ERR(0, 1408, __pyx_L1_error)
     __pyx_t_9 = NULL;
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     goto __pyx_L4_unpacking_done;
@@ -16566,7 +16389,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_9 = NULL;
     if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-    __PYX_ERR(0, 1387, __pyx_L1_error)
+    __PYX_ERR(0, 1408, __pyx_L1_error)
     __pyx_L4_unpacking_done:;
   }
   __pyx_v_sout = __pyx_t_1;
@@ -16574,36 +16397,36 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   __pyx_v_serr = __pyx_t_4;
   __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":1388
+  /* "pywrapfst.pyx":1409
  *                 addr(sstrm), b"_repr_svg")
  *     (sout, serr) = proc.communicate(sstrm.str())
  *     if proc.returncode != 0:  # Just to be explicit.             # <<<<<<<<<<<<<<
  *       raise subprocess.CalledProcessError(proc.returncode, self._DOT_TSVG)
  *     return sout.decode("utf8")
  */
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_returncode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1388, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_returncode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1409, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_int_0, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1388, __pyx_L1_error)
+  __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_int_0, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1409, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_10 < 0)) __PYX_ERR(0, 1388, __pyx_L1_error)
+  __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_10 < 0)) __PYX_ERR(0, 1409, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":1389
+    /* "pywrapfst.pyx":1410
  *     (sout, serr) = proc.communicate(sstrm.str())
  *     if proc.returncode != 0:  # Just to be explicit.
  *       raise subprocess.CalledProcessError(proc.returncode, self._DOT_TSVG)             # <<<<<<<<<<<<<<
  *     return sout.decode("utf8")
  * 
  */
-    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1389, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_subprocess); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1410, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_CalledProcessError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1389, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_CalledProcessError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1410, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_returncode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1389, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_returncode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1410, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_DOT_TSVG); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1389, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_DOT_TSVG); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1410, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_2 = NULL;
     __pyx_t_11 = 0;
@@ -16620,7 +16443,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_1)) {
       PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_t_5, __pyx_t_3};
-      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1389, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1410, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -16630,7 +16453,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
       PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_t_5, __pyx_t_3};
-      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1389, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1410, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -16638,7 +16461,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     } else
     #endif
     {
-      __pyx_t_12 = PyTuple_New(2+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1389, __pyx_L1_error)
+      __pyx_t_12 = PyTuple_New(2+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1410, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_12);
       if (__pyx_t_2) {
         __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_2); __pyx_t_2 = NULL;
@@ -16649,16 +16472,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
       PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_3);
       __pyx_t_5 = 0;
       __pyx_t_3 = 0;
-      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_12, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1389, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_12, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1410, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
     }
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 1389, __pyx_L1_error)
+    __PYX_ERR(0, 1410, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1388
+    /* "pywrapfst.pyx":1409
  *                 addr(sstrm), b"_repr_svg")
  *     (sout, serr) = proc.communicate(sstrm.str())
  *     if proc.returncode != 0:  # Just to be explicit.             # <<<<<<<<<<<<<<
@@ -16667,7 +16490,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1390
+  /* "pywrapfst.pyx":1411
  *     if proc.returncode != 0:  # Just to be explicit.
  *       raise subprocess.CalledProcessError(proc.returncode, self._DOT_TSVG)
  *     return sout.decode("utf8")             # <<<<<<<<<<<<<<
@@ -16675,16 +16498,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  *   def __repr__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_sout, __pyx_n_s_decode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1390, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_sout, __pyx_n_s_decode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1411, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1390, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1411, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1364
+  /* "pywrapfst.pyx":1385
  * 
  *   # IPython notebook magic to produce an SVG of the FST.
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -16711,7 +16534,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1392
+/* "pywrapfst.pyx":1413
  *     return sout.decode("utf8")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -16744,7 +16567,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1393
+  /* "pywrapfst.pyx":1414
  * 
  *   def __repr__(self):
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))             # <<<<<<<<<<<<<<
@@ -16752,20 +16575,20 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
  *   def __init__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Fst_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1393, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Fst_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1414, __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 '%s'", "fst_type");
-    __PYX_ERR(0, 1393, __pyx_L1_error)
+    __PYX_ERR(0, 1414, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1393, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1414, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1393, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1414, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1393, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1414, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -16783,7 +16606,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 1393, __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, 1414, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -16793,7 +16616,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5};
-    __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, 1393, __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, 1414, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -16801,7 +16624,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1393, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1414, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -16812,7 +16635,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
     PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1393, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1414, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -16821,7 +16644,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1392
+  /* "pywrapfst.pyx":1413
  *     return sout.decode("utf8")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -16845,7 +16668,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_2__repr__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1395
+/* "pywrapfst.pyx":1416
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -16881,28 +16704,28 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1396
+  /* "pywrapfst.pyx":1417
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1417, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1397
+  /* "pywrapfst.pyx":1418
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *    # Other magic methods.
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1397, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1418, __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, 1397, __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, 1418, __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, 1397, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1418, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -16916,14 +16739,14 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
     }
   }
   if (!__pyx_t_5) {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1397, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_GOTREF(__pyx_t_3);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1397, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -16932,20 +16755,20 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1397, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1397, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1418, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
       __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1397, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -16962,14 +16785,14 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
     }
   }
   if (!__pyx_t_4) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -16978,20 +16801,20 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1396, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1417, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -16999,9 +16822,9 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
   __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, 1396, __pyx_L1_error)
+  __PYX_ERR(0, 1417, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1395
+  /* "pywrapfst.pyx":1416
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -17024,7 +16847,7 @@ static int __pyx_pf_9pywrapfst_4_Fst_4__init__(struct __pyx_obj_9pywrapfst__Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1401
+/* "pywrapfst.pyx":1422
  *    # Other magic methods.
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -17053,7 +16876,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__str__(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1423
  * 
  *   def __str__(self):
  *     return self.text(acceptor=self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
@@ -17063,30 +16886,30 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__str__(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "text");
-    __PYX_ERR(0, 1402, __pyx_L1_error)
+    __PYX_ERR(0, 1423, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1423, __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 '%s'", "_fst");
-    __PYX_ERR(0, 1402, __pyx_L1_error)
+    __PYX_ERR(0, 1423, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1403
+  /* "pywrapfst.pyx":1424
  *   def __str__(self):
  *     return self.text(acceptor=self._fst.get().Properties(fst.kAcceptor, True) ==
  *         fst.kAcceptor,             # <<<<<<<<<<<<<<
  *         show_weight_one=self._fst.get().Properties(fst.kWeighted, True) ==
  *         fst.kWeighted)
  */
-  __pyx_t_3 = __Pyx_PyBool_FromLong((__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong((__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_acceptor, __pyx_t_3) < 0) __PYX_ERR(0, 1402, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_acceptor, __pyx_t_3) < 0) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1404
+  /* "pywrapfst.pyx":1425
  *     return self.text(acceptor=self._fst.get().Properties(fst.kAcceptor, True) ==
  *         fst.kAcceptor,
  *         show_weight_one=self._fst.get().Properties(fst.kWeighted, True) ==             # <<<<<<<<<<<<<<
@@ -17095,29 +16918,29 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__str__(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1404, __pyx_L1_error)
+    __PYX_ERR(0, 1425, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1405
+  /* "pywrapfst.pyx":1426
  *         fst.kAcceptor,
  *         show_weight_one=self._fst.get().Properties(fst.kWeighted, True) ==
  *         fst.kWeighted)             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-  __pyx_t_3 = __Pyx_PyBool_FromLong((__pyx_v_self->_fst.get()->Properties(fst::kWeighted, 1) == fst::kWeighted)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1404, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong((__pyx_v_self->_fst.get()->Properties(fst::kWeighted, 1) == fst::kWeighted)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1425, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_show_weight_one, __pyx_t_3) < 0) __PYX_ERR(0, 1402, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_show_weight_one, __pyx_t_3) < 0) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1423
  * 
  *   def __str__(self):
  *     return self.text(acceptor=self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
  *         fst.kAcceptor,
  *         show_weight_one=self._fst.get().Properties(fst.kWeighted, True) ==
  */
-  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1402, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1423, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -17125,7 +16948,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__str__(struct __pyx_obj_9pywrapfst_
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1401
+  /* "pywrapfst.pyx":1422
  *    # Other magic methods.
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -17146,12 +16969,12 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__str__(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1407
+/* "pywrapfst.pyx":1428
  *         fst.kWeighted)
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -17168,7 +16991,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __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, 1428, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_9arc_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -17183,14 +17006,14 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1407, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1428, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1407, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1428, __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, 1407, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1428, __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;
@@ -17199,26 +17022,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1408
- * 
- *   cpdef string arc_type(self):
+  /* "pywrapfst.pyx":1434
+ *     Returns a string indicating the arc type.
+ *     """
  *     return self._fst.get().ArcType()             # <<<<<<<<<<<<<<
  * 
  *   cpdef ArcIterator arcs(self, int64 state):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1408, __pyx_L1_error)
+    __PYX_ERR(0, 1434, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1407
+  /* "pywrapfst.pyx":1428
  *         fst.kWeighted)
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
   /* function exit code */
@@ -17235,6 +17058,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_8arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -17252,7 +17076,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8arc_type(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1428, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17269,7 +17093,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8arc_type(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1410
+/* "pywrapfst.pyx":1436
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -17292,11 +17116,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1410, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1436, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_11arcs)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1410, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1436, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -17310,14 +17134,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -17326,26 +17150,26 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1410, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1436, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1410, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1436, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -17354,7 +17178,7 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1424
+  /* "pywrapfst.pyx":1450
  *     See also: `mutable_arcs`, `states`.
  *     """
  *     return ArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -17362,9 +17186,9 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
  *   cpdef _Fst copy(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1424, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1424, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -17372,14 +17196,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1424, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1410
+  /* "pywrapfst.pyx":1436
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -17405,14 +17229,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_11arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_10arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving some state=.\n\n    Args:\n      s: The source state ID.\n\n    Returns:\n      An ArcIterator over arcs leaving state `state`.\n\n    See also: `mutable_arcs`, `states`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_10arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An ArcIterator.\n\n    See also: `mutable_arcs`, `states`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_11arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1410, __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, 1436, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -17433,7 +17257,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arcs(struct __pyx_obj_9pywrapfst__F
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1410, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1436, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17450,7 +17274,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arcs(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1426
+/* "pywrapfst.pyx":1452
  *     return ArcIterator(self, state)
  * 
  *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
@@ -17471,7 +17295,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1426, __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, 1452, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_13copy)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -17487,14 +17311,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1426, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1452, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1426, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1452, __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, 1426, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 1452, __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;
@@ -17503,7 +17327,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1432
+  /* "pywrapfst.pyx":1458
  *     Makes a copy of the FST.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -17513,15 +17337,15 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1432, __pyx_L1_error)
+    __PYX_ERR(0, 1458, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1432, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1458, __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":1426
+  /* "pywrapfst.pyx":1452
  *     return ArcIterator(self, state)
  * 
  *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
@@ -17563,7 +17387,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12copy(struct __pyx_obj_9pywrapfst__F
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1426, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1452, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17580,7 +17404,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12copy(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1434
+/* "pywrapfst.pyx":1460
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -17591,7 +17415,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12copy(struct __pyx_obj_9pywrapfst__F
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_filename, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":1436
+  /* "pywrapfst.pyx":1462
  *   cpdef void draw(self,
  *                   filename,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -17600,7 +17424,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1437
+  /* "pywrapfst.pyx":1463
  *                   filename,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -17609,7 +17433,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1438
+  /* "pywrapfst.pyx":1464
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
  *                   SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -17618,7 +17442,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1439
+  /* "pywrapfst.pyx":1465
  *                   _SymbolTable osymbols=None,
  *                   SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -17626,11 +17450,11 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  *                   double width=8.5,
  */
   bool __pyx_v_acceptor = ((bool)0);
-  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_b_);
+  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_b__5);
   double __pyx_v_width = ((double)8.5);
   double __pyx_v_height = ((double)11.0);
 
-  /* "pywrapfst.pyx":1443
+  /* "pywrapfst.pyx":1469
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -17639,7 +17463,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   bool __pyx_v_portrait = ((bool)0);
 
-  /* "pywrapfst.pyx":1444
+  /* "pywrapfst.pyx":1470
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -17653,7 +17477,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   __pyx_t_10basictypes_int32 __pyx_v_precision = ((__pyx_t_10basictypes_int32)5);
   PyObject *__pyx_v_float_format = ((PyObject *)__pyx_n_b_g);
 
-  /* "pywrapfst.pyx":1450
+  /* "pywrapfst.pyx":1476
  *                   int32 precision=5,
  *                   float_format=b"g",
  *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
@@ -17737,7 +17561,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":1434
+  /* "pywrapfst.pyx":1460
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -17748,28 +17572,28 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1434, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1460, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_15draw)) {
-      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_8);
-      __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_11);
-      __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1434, __pyx_L1_error)
+      __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1460, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_12);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_13 = __pyx_t_1; __pyx_t_14 = NULL;
@@ -17787,7 +17611,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_13)) {
         PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_filename, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1434, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1460, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -17805,7 +17629,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_13)) {
         PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_filename, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1434, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1460, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -17821,7 +17645,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
       } else
       #endif
       {
-        __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1434, __pyx_L1_error)
+        __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1460, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_16);
         if (__pyx_t_14) {
           __Pyx_GIVEREF(__pyx_t_14); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_14); __pyx_t_14 = NULL;
@@ -17874,7 +17698,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
         __pyx_t_10 = 0;
         __pyx_t_11 = 0;
         __pyx_t_12 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1434, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1460, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
       }
@@ -17886,36 +17710,36 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1486
+  /* "pywrapfst.pyx":1510
  *     See also: `text`.
  *     """
  *     cdef string filename_string = tostring(filename)             # <<<<<<<<<<<<<<
  *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string.c_str()))
+ *     ostrm.reset(new ofstream(filename_string))
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1486, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1510, __pyx_L1_error)
   __pyx_v_filename_string = __pyx_t_17;
 
-  /* "pywrapfst.pyx":1488
+  /* "pywrapfst.pyx":1512
  *     cdef string filename_string = tostring(filename)
  *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string.c_str()))             # <<<<<<<<<<<<<<
+ *     ostrm.reset(new ofstream(filename_string))             # <<<<<<<<<<<<<<
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:
  */
-  __pyx_v_ostrm.reset(new std::ofstream(__pyx_v_filename_string.c_str()));
+  __pyx_v_ostrm.reset(new std::ofstream(__pyx_v_filename_string));
 
-  /* "pywrapfst.pyx":1489
+  /* "pywrapfst.pyx":1513
  *     cdef unique_ptr[ofstream] ostrm
- *     ostrm.reset(new ofstream(filename_string.c_str()))
+ *     ostrm.reset(new ofstream(filename_string))
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL             # <<<<<<<<<<<<<<
  *     if ssymbols is not None:
  *       ssymbols_ptr = ssymbols._table
  */
   __pyx_v_ssymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":1490
- *     ostrm.reset(new ofstream(filename_string.c_str()))
+  /* "pywrapfst.pyx":1514
+ *     ostrm.reset(new ofstream(filename_string))
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
  *       ssymbols_ptr = ssymbols._table
@@ -17925,7 +17749,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1491
+    /* "pywrapfst.pyx":1515
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:
  *       ssymbols_ptr = ssymbols._table             # <<<<<<<<<<<<<<
@@ -17934,13 +17758,13 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1491, __pyx_L1_error)
+      __PYX_ERR(0, 1515, __pyx_L1_error)
     }
     __pyx_t_20 = __pyx_v_ssymbols->__pyx_base.__pyx_base._table;
     __pyx_v_ssymbols_ptr = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1490
- *     ostrm.reset(new ofstream(filename_string.c_str()))
+    /* "pywrapfst.pyx":1514
+ *     ostrm.reset(new ofstream(filename_string))
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
  *       ssymbols_ptr = ssymbols._table
@@ -17948,7 +17772,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   }
 
-  /* "pywrapfst.pyx":1492
+  /* "pywrapfst.pyx":1516
  *     if ssymbols is not None:
  *       ssymbols_ptr = ssymbols._table
  *     fst.DrawFst(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -17957,10 +17781,10 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1492, __pyx_L1_error)
+    __PYX_ERR(0, 1516, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1493
+  /* "pywrapfst.pyx":1517
  *       ssymbols_ptr = ssymbols._table
  *     fst.DrawFst(deref(self._fst),
  *         self._fst.get().InputSymbols() if isymbols is None             # <<<<<<<<<<<<<<
@@ -17971,12 +17795,12 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   if ((__pyx_t_19 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-      __PYX_ERR(0, 1493, __pyx_L1_error)
+      __PYX_ERR(0, 1517, __pyx_L1_error)
     }
     __pyx_t_21 = __pyx_v_self->_fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1494
+    /* "pywrapfst.pyx":1518
  *     fst.DrawFst(deref(self._fst),
  *         self._fst.get().InputSymbols() if isymbols is None
  *         else isymbols._table,             # <<<<<<<<<<<<<<
@@ -17985,12 +17809,12 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1494, __pyx_L1_error)
+      __PYX_ERR(0, 1518, __pyx_L1_error)
     }
     __pyx_t_21 = __pyx_v_isymbols->_table;
   }
 
-  /* "pywrapfst.pyx":1495
+  /* "pywrapfst.pyx":1519
  *         self._fst.get().InputSymbols() if isymbols is None
  *         else isymbols._table,
  *         self._fst.get().OutputSymbols() if osymbols is None             # <<<<<<<<<<<<<<
@@ -18001,12 +17825,12 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   if ((__pyx_t_19 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-      __PYX_ERR(0, 1495, __pyx_L1_error)
+      __PYX_ERR(0, 1519, __pyx_L1_error)
     }
     __pyx_t_22 = __pyx_v_self->_fst.get()->OutputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1496
+    /* "pywrapfst.pyx":1520
  *         else isymbols._table,
  *         self._fst.get().OutputSymbols() if osymbols is None
  *         else osymbols._table,             # <<<<<<<<<<<<<<
@@ -18015,30 +17839,30 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1496, __pyx_L1_error)
+      __PYX_ERR(0, 1520, __pyx_L1_error)
     }
     __pyx_t_22 = __pyx_v_osymbols->_table;
   }
 
-  /* "pywrapfst.pyx":1497
+  /* "pywrapfst.pyx":1521
  *         self._fst.get().OutputSymbols() if osymbols is None
  *         else osymbols._table,
  *         ssymbols_ptr, acceptor, tostring(title), width, height, portrait,             # <<<<<<<<<<<<<<
  *         vertical, ranksep, nodesep, fontsize, precision,
  *         tostring(float_format), show_weight_one, ostrm.get(),
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1497, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1521, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1499
+  /* "pywrapfst.pyx":1523
  *         ssymbols_ptr, acceptor, tostring(title), width, height, portrait,
  *         vertical, ranksep, nodesep, fontsize, precision,
  *         tostring(float_format), show_weight_one, ostrm.get(),             # <<<<<<<<<<<<<<
  *         filename_string)
  * 
  */
-  __pyx_t_23 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1499, __pyx_L1_error)
+  __pyx_t_23 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1523, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1492
+  /* "pywrapfst.pyx":1516
  *     if ssymbols is not None:
  *       ssymbols_ptr = ssymbols._table
  *     fst.DrawFst(deref(self._fst),             # <<<<<<<<<<<<<<
@@ -18047,7 +17871,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   fst::script::DrawFst((*__pyx_v_self->_fst), __pyx_t_21, __pyx_t_22, __pyx_v_ssymbols_ptr, __pyx_v_acceptor, __pyx_t_17, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_t_23, __pyx_v_show_weight_one, __pyx_v_ostrm.get(), __pyx_v_filename_string);
 
-  /* "pywrapfst.pyx":1434
+  /* "pywrapfst.pyx":1460
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18080,7 +17904,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_14draw[] = "\n    draw(self, filename, isymbols=None, osymbols=None, ssymbols=None,\n         acceptor=False, title=\"\", width=8.5, height=11, portrait=False,\n         vertical=False, ranksep=0.4, nodesep=0.25, fontsize=14,\n         precision=5, float_format=\"g\", show_weight_one=False):\n\n    Writes out the FST in Graphviz text format.\n\n    This method writes out the FST in the dot graph description language. The\n    graph can be rendered using the `dot` executable provided by Graphviz.\n\n    Args:\n      filename: The string location of the output dot/Graphviz file.\n      isymbols: An optional symbol table used to label input symbols.\n      osymbols: An optional symbol table used to label output symbols.\n      ssymbols: An optional symbol table used to label states.\n      acceptor: Should the figure be rendered in acceptor format if possible?\n      title: An optional string indicating the figure title.\n      width: The figure width, in inches.\n      height: The figure height, in inches.\n      portrait: Should the figure be rendered in portrait rather than\n          landscape?\n      vertical: Should the figure be rendered bottom-to-top rather than\n          left-to-right?\n      ranksep: The minimum separation separation between ranks, in inches.\n      nodesep: The minimum separation between nodes, in inches.\n      fontsize: Font size, in points.\n      precision: Numeric precision for floats, in number of chars.\n      float_format: One of: 'e', 'f' or 'g'.\n      show_weight_one: Should weights equivalent to semiring One be printed?\n\n    For more information about the rendering options, see `man dot`.\n\n    See also: `text`.\n    ";
+static char __pyx_doc_9pywrapfst_4_Fst_14draw[] = "\n    draw(self, filename, isymbols=None, osymbols=None, ssymbols=None,\n         acceptor=False, title=\"\", width=8.5, height=11, portrait=False,\n         vertical=False, ranksep=0.4, nodesep=0.25, fontsize=14,\n         precision=5, float_format=\"g\", show_weight_one=False):\n\n    Writes out the FST in Graphviz text format.\n\n    This method writes out the FST in the dot graph description language. The\n    graph can be rendered using the `dot` executable provided by Graphviz.\n\n    Args:\n      filename: The string location of the output dot/Graphviz file.\n      isymbols: An optional symbol table used to label input symbols.\n      osymbols: An optional symbol table used to label output symbols.\n      ssymbols: An optional symbol table used to label states.\n      acceptor: Should the figure be rendered in acceptor format if possible?\n      title: An optional string indicating the figure title.\n      width: The figure width, in inches.\n      height: The figure height, in inches.\n      portrait: Should the figure be rendered in portrait rather than\n          landscape?\n      vertical: Should the figure be rendered bottom-to-top rather than\n          left-to-right?\n      ranksep: The minimum separation separation between ranks, in inches.\n      nodesep: The minimum separation between nodes, in inches.\n      fontsize: Font size, in points.\n      precision: Numeric precision for floats, in number of chars.\n      float_format: One of: 'e', 'f' or 'g'.\n      show_weight_one: Should weights equivalent to semiring One be printed?\n\n    See also: `text`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_filename = 0;
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = 0;
@@ -18105,7 +17929,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_title,&__pyx_n_s_width,&__pyx_n_s_height,&__pyx_n_s_portrait,&__pyx_n_s_vertical,&__pyx_n_s_ranksep,&__pyx_n_s_nodesep,&__pyx_n_s_fontsize,&__pyx_n_s_precision,&__pyx_n_s_float_format,&__pyx_n_s_show_weight_one,0};
     PyObject* values[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":1436
+    /* "pywrapfst.pyx":1462
  *   cpdef void draw(self,
  *                   filename,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -18114,7 +17938,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1437
+    /* "pywrapfst.pyx":1463
  *                   filename,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -18123,7 +17947,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1438
+    /* "pywrapfst.pyx":1464
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
  *                   SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -18131,7 +17955,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
  *                   title=b"",
  */
     values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b_);
+    values[5] = ((PyObject *)__pyx_kp_b__5);
     values[14] = ((PyObject *)__pyx_n_b_g);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -18238,7 +18062,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1434, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1460, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -18267,10 +18091,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[3]);
     if (values[4]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1439, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1465, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1439
+      /* "pywrapfst.pyx":1465
  *                   _SymbolTable osymbols=None,
  *                   SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -18281,20 +18105,20 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
     }
     __pyx_v_title = values[5];
     if (values[6]) {
-      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1441, __pyx_L3_error)
+      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1467, __pyx_L3_error)
     } else {
       __pyx_v_width = ((double)8.5);
     }
     if (values[7]) {
-      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1442, __pyx_L3_error)
+      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1468, __pyx_L3_error)
     } else {
       __pyx_v_height = ((double)11.0);
     }
     if (values[8]) {
-      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1443, __pyx_L3_error)
+      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1469, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1443
+      /* "pywrapfst.pyx":1469
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -18304,10 +18128,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
       __pyx_v_portrait = ((bool)0);
     }
     if (values[9]) {
-      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1444, __pyx_L3_error)
+      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1470, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1444
+      /* "pywrapfst.pyx":1470
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -18317,31 +18141,31 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
       __pyx_v_vertical = ((bool)0);
     }
     if (values[10]) {
-      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1445, __pyx_L3_error)
+      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1471, __pyx_L3_error)
     } else {
       __pyx_v_ranksep = ((double)0.4);
     }
     if (values[11]) {
-      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1446, __pyx_L3_error)
+      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1472, __pyx_L3_error)
     } else {
       __pyx_v_nodesep = ((double)0.25);
     }
     if (values[12]) {
-      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1447, __pyx_L3_error)
+      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1473, __pyx_L3_error)
     } else {
       __pyx_v_fontsize = ((__pyx_t_10basictypes_int32)14);
     }
     if (values[13]) {
-      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1448, __pyx_L3_error)
+      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1474, __pyx_L3_error)
     } else {
       __pyx_v_precision = ((__pyx_t_10basictypes_int32)5);
     }
     __pyx_v_float_format = values[14];
     if (values[15]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1450, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1476, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1450
+      /* "pywrapfst.pyx":1476
  *                   int32 precision=5,
  *                   float_format=b"g",
  *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
@@ -18353,18 +18177,18 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_15draw(PyObject *__pyx_v_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1434, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1460, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1436, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1437, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1438, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1462, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1463, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1464, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4_Fst_14draw(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), __pyx_v_filename, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_title, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_v_float_format, __pyx_v_show_weight_one);
 
-  /* "pywrapfst.pyx":1434
+  /* "pywrapfst.pyx":1460
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18405,7 +18229,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14draw(struct __pyx_obj_9pywrapfst__F
   __pyx_t_1.float_format = __pyx_v_float_format;
   __pyx_t_1.show_weight_one = __pyx_v_show_weight_one;
   __pyx_vtabptr_9pywrapfst__Fst->draw(__pyx_v_self, __pyx_v_filename, 1, &__pyx_t_1); 
-  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1434, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -18422,7 +18246,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14draw(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1502
+/* "pywrapfst.pyx":1526
  *         filename_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18446,11 +18270,11 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1502, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1526, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_17final)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1502, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1526, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18464,14 +18288,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1502, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1526, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1502, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1526, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -18480,26 +18304,26 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1502, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1526, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1502, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1526, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1502, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1526, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1502, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1526, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18508,20 +18332,20 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1517
+  /* "pywrapfst.pyx":1541
  *       FstIndexError: State index out of range.
  *     """
  *     cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     return weight
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1517, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 1517, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 1541, __pyx_L1_error)
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1518
+  /* "pywrapfst.pyx":1542
  *     """
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
@@ -18530,15 +18354,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_weight");
-    __PYX_ERR(0, 1518, __pyx_L1_error)
+    __PYX_ERR(0, 1542, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1518, __pyx_L1_error)
+    __PYX_ERR(0, 1542, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
 
-  /* "pywrapfst.pyx":1519
+  /* "pywrapfst.pyx":1543
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     return weight             # <<<<<<<<<<<<<<
@@ -18550,7 +18374,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
   __pyx_r = __pyx_v_weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1502
+  /* "pywrapfst.pyx":1526
  *         filename_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18584,7 +18408,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17final(PyObject *__pyx_v_self, PyObj
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("final (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1502, __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, 1526, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -18605,7 +18429,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16final(struct __pyx_obj_9pywrapfst__
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("final", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1502, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1526, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18622,12 +18446,12 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16final(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1521
+/* "pywrapfst.pyx":1545
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().FstType()
- * 
+ *     """
+ *     fst_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_19fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -18644,7 +18468,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1521, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1545, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_19fst_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -18659,14 +18483,14 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1521, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1545, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1521, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1545, __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, 1521, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1545, __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;
@@ -18675,26 +18499,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1522
- * 
- *   cpdef string fst_type(self):
+  /* "pywrapfst.pyx":1551
+ *     Returns a string indicating the FST type.
+ *     """
  *     return self._fst.get().FstType()             # <<<<<<<<<<<<<<
  * 
  *   cpdef _FstSymbolTable input_symbols(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1522, __pyx_L1_error)
+    __PYX_ERR(0, 1551, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->FstType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1521
+  /* "pywrapfst.pyx":1545
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().FstType()
- * 
+ *     """
+ *     fst_type(self)
  */
 
   /* function exit code */
@@ -18711,6 +18535,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_19fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_18fst_type[] = "\n    fst_type(self)\n\n    Returns a string indicating the FST type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_19fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -18728,7 +18553,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18fst_type(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("fst_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1521, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18745,16 +18570,17 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18fst_type(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1524
+/* "pywrapfst.pyx":1553
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._fst.get().InputSymbols() == NULL:
- *       return
+ *     """
+ *     input_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_21input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  fst::SymbolTable *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -18767,7 +18593,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1524, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1553, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_21input_symbols)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -18783,14 +18609,14 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1524, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1553, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1524, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1553, __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__FstSymbolTable))))) __PYX_ERR(0, 1524, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTable))))) __PYX_ERR(0, 1553, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18799,92 +18625,81 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1525
- * 
- *   cpdef _FstSymbolTable input_symbols(self):
- *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1562
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().InputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1525, __pyx_L1_error)
+    __PYX_ERR(0, 1562, __pyx_L1_error)
   }
-  __pyx_t_5 = ((__pyx_v_self->_fst.get()->InputSymbols() == NULL) != 0);
-  if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1526
- *   cpdef _FstSymbolTable input_symbols(self):
- *     if self._fst.get().InputSymbols() == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().InputSymbols()), self._fst)
+  /* "pywrapfst.pyx":1561
+ *     See also: `input_symbols`.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *       self._fst.get().InputSymbols())
+ *     if syms == NULL:
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->InputSymbols());
 
-    /* "pywrapfst.pyx":1525
- * 
- *   cpdef _FstSymbolTable input_symbols(self):
- *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1563
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
+ *     return _init_FstSymbolTable(syms, self._fst)
  */
-  }
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
 
-  /* "pywrapfst.pyx":1527
- *     if self._fst.get().InputSymbols() == NULL:
- *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols()), self._fst)
+    /* "pywrapfst.pyx":1564
+ *       self._fst.get().InputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  */
-  __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1528
+    /* "pywrapfst.pyx":1563
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().InputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().InputSymbols()), self._fst)             # <<<<<<<<<<<<<<
- * 
- *   cpdef size_t num_arcs(self, int64 state) except *:
+ *     return _init_FstSymbolTable(syms, self._fst)
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1528, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1527
- *     if self._fst.get().InputSymbols() == NULL:
+  /* "pywrapfst.pyx":1565
+ *     if syms == NULL:
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._fst.get().InputSymbols()), self._fst)
+ *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
  * 
+ *   cpdef size_t num_arcs(self, int64 state) except *:
  */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1528, __pyx_L1_error)
+    __PYX_ERR(0, 1565, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1528
- *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().InputSymbols()), self._fst)             # <<<<<<<<<<<<<<
- * 
- *   cpdef size_t num_arcs(self, int64 state) except *:
- */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->InputSymbols()), __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1527, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(__pyx_v_syms, __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1565, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1524
+  /* "pywrapfst.pyx":1553
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._fst.get().InputSymbols() == NULL:
- *       return
+ *     """
+ *     input_symbols(self)
  */
 
   /* function exit code */
@@ -18903,6 +18718,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_21input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_20input_symbols[] = "\n    input_symbols(self)\n\n    Returns the FST's input symbol table, or None if none is present.\n\n    See also: `input_symbols`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_21input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -18920,7 +18736,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20input_symbols(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1524, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1553, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18937,8 +18753,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20input_symbols(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1530
- *         self._fst.get().InputSymbols()), self._fst)
+/* "pywrapfst.pyx":1567
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -18963,10 +18779,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1530, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1567, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_23num_arcs)) {
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1530, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1567, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18980,14 +18796,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1567, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1567, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -18996,26 +18812,26 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1567, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1530, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1567, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1567, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1530, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1567, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_7;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19024,7 +18840,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1547
+  /* "pywrapfst.pyx":1584
  *     See also: `num_states`.
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
@@ -19033,11 +18849,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1547, __pyx_L1_error)
+    __PYX_ERR(0, 1584, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1548
+  /* "pywrapfst.pyx":1585
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19047,23 +18863,23 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __pyx_t_8 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":1549
+    /* "pywrapfst.pyx":1586
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1549, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1586, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1549, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1586, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 1549, __pyx_L1_error)
+    __PYX_ERR(0, 1586, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1548
+    /* "pywrapfst.pyx":1585
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19072,7 +18888,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
  */
   }
 
-  /* "pywrapfst.pyx":1550
+  /* "pywrapfst.pyx":1587
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19082,8 +18898,8 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1530
- *         self._fst.get().InputSymbols()), self._fst)
+  /* "pywrapfst.pyx":1567
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -19114,7 +18930,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_23num_arcs(PyObject *__pyx_v_self, Py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1530, __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, 1567, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19136,8 +18952,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22num_arcs(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1530, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1530, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1567, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1567, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19154,7 +18970,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22num_arcs(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1552
+/* "pywrapfst.pyx":1589
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19180,10 +18996,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1552, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1589, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_25num_input_epsilons)) {
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1552, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1589, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19197,14 +19013,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1589, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1589, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -19213,26 +19029,26 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1589, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1552, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1589, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1589, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1552, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1589, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_7;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19241,7 +19057,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1569
+  /* "pywrapfst.pyx":1606
  *     See also: `num_output_epsilons`.
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -19250,11 +19066,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1569, __pyx_L1_error)
+    __PYX_ERR(0, 1606, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1570
+  /* "pywrapfst.pyx":1607
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19264,23 +19080,23 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __pyx_t_8 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":1571
+    /* "pywrapfst.pyx":1608
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1571, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1608, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1571, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1608, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 1571, __pyx_L1_error)
+    __PYX_ERR(0, 1608, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1570
+    /* "pywrapfst.pyx":1607
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19289,7 +19105,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1572
+  /* "pywrapfst.pyx":1609
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19299,7 +19115,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1552
+  /* "pywrapfst.pyx":1589
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19331,7 +19147,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_25num_input_epsilons(PyObject *__pyx_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_input_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1552, __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, 1589, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19353,8 +19169,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_input_epsilons(struct __pyx_obj
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_input_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1552, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1589, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1589, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19371,7 +19187,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_input_epsilons(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1574
+/* "pywrapfst.pyx":1611
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19397,10 +19213,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1574, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1611, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_27num_output_epsilons)) {
-      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1574, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1611, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19414,14 +19230,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1574, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1611, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1574, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1611, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -19430,26 +19246,26 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1574, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1611, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1574, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1611, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1574, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1611, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1574, __pyx_L1_error)
+      __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1611, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_7;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19458,7 +19274,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1591
+  /* "pywrapfst.pyx":1628
  *     See also: `num_input_epsilons`.
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -19467,11 +19283,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1591, __pyx_L1_error)
+    __PYX_ERR(0, 1628, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1592
+  /* "pywrapfst.pyx":1629
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19481,23 +19297,23 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   __pyx_t_8 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":1593
+    /* "pywrapfst.pyx":1630
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1593, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1630, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1593, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1630, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 1593, __pyx_L1_error)
+    __PYX_ERR(0, 1630, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1592
+    /* "pywrapfst.pyx":1629
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19506,7 +19322,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":1594
+  /* "pywrapfst.pyx":1631
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -19516,7 +19332,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1574
+  /* "pywrapfst.pyx":1611
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19548,7 +19364,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_27num_output_epsilons(PyObject *__pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_output_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1574, __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, 1611, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19570,8 +19386,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_output_epsilons(struct __pyx_ob
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_output_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1574, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1574, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1611, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1611, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19588,16 +19404,17 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_output_epsilons(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1596
+/* "pywrapfst.pyx":1633
  *     return result
  * 
  *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._fst.get().OutputSymbols() == NULL:
- *       return
+ *     """
+ *     output_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_29output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_output_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  fst::SymbolTable *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -19610,7 +19427,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1596, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1633, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_29output_symbols)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -19626,14 +19443,14 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1596, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1633, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1596, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1633, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTable))))) __PYX_ERR(0, 1596, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTable))))) __PYX_ERR(0, 1633, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19642,92 +19459,81 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1597
- * 
- *   cpdef _FstSymbolTable output_symbols(self):
- *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1642
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().OutputSymbols())             # <<<<<<<<<<<<<<
+ *     if syms == NULL:
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1597, __pyx_L1_error)
+    __PYX_ERR(0, 1642, __pyx_L1_error)
   }
-  __pyx_t_5 = ((__pyx_v_self->_fst.get()->OutputSymbols() == NULL) != 0);
-  if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1598
- *   cpdef _FstSymbolTable output_symbols(self):
- *     if self._fst.get().OutputSymbols() == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().OutputSymbols()), self._fst)
+  /* "pywrapfst.pyx":1641
+ *     See also: `input_symbols`.
+ *     """
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
+ *       self._fst.get().OutputSymbols())
+ *     if syms == NULL:
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
+  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->OutputSymbols());
 
-    /* "pywrapfst.pyx":1597
- * 
- *   cpdef _FstSymbolTable output_symbols(self):
- *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1643
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
+ *     return _init_FstSymbolTable(syms, self._fst)
  */
-  }
+  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  if (__pyx_t_5) {
 
-  /* "pywrapfst.pyx":1599
- *     if self._fst.get().OutputSymbols() == NULL:
- *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._fst.get().OutputSymbols()), self._fst)
+    /* "pywrapfst.pyx":1644
+ *       self._fst.get().OutputSymbols())
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  */
-  __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1600
+    /* "pywrapfst.pyx":1643
+ *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+ *       self._fst.get().OutputSymbols())
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().OutputSymbols()), self._fst)             # <<<<<<<<<<<<<<
- * 
- *   cpdef uint64 properties(self, uint64 mask, bool test):
+ *     return _init_FstSymbolTable(syms, self._fst)
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1600, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1599
- *     if self._fst.get().OutputSymbols() == NULL:
+  /* "pywrapfst.pyx":1645
+ *     if syms == NULL:
  *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._fst.get().OutputSymbols()), self._fst)
+ *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
  * 
+ *   cpdef uint64 properties(self, uint64 mask, bool test):
  */
+  __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1600, __pyx_L1_error)
+    __PYX_ERR(0, 1645, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1600
- *       return
- *     return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
- *         self._fst.get().OutputSymbols()), self._fst)             # <<<<<<<<<<<<<<
- * 
- *   cpdef uint64 properties(self, uint64 mask, bool test):
- */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->OutputSymbols()), __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1599, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(__pyx_v_syms, __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1645, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1596
+  /* "pywrapfst.pyx":1633
  *     return result
  * 
  *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     if self._fst.get().OutputSymbols() == NULL:
- *       return
+ *     """
+ *     output_symbols(self)
  */
 
   /* function exit code */
@@ -19746,6 +19552,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_29output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_28output_symbols[] = "\n    output_symbols(self)\n\n    Returns the FST's output symbol table, or None if none is present.\n\n    See also: `input_symbols`.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_29output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -19763,7 +19570,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28output_symbols(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1596, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1633, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19780,8 +19587,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28output_symbols(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1602
- *         self._fst.get().OutputSymbols()), self._fst)
+/* "pywrapfst.pyx":1647
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
@@ -19806,12 +19613,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1602, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1647, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_31properties)) {
-      __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1602, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1647, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1602, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1647, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -19829,7 +19636,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
       #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, 1602, __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, 1647, __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;
@@ -19839,7 +19646,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
       #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, 1602, __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, 1647, __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;
@@ -19847,7 +19654,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1602, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1647, __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;
@@ -19858,12 +19665,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
         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, 1602, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1647, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_9 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_9 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1602, __pyx_L1_error)
+      __pyx_t_9 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_9 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1647, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_9;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19872,7 +19679,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1620
+  /* "pywrapfst.pyx":1665
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._fst.get().Properties(mask, test)             # <<<<<<<<<<<<<<
@@ -19881,13 +19688,13 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1620, __pyx_L1_error)
+    __PYX_ERR(0, 1665, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Properties(__pyx_v_mask, __pyx_v_test);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1602
- *         self._fst.get().OutputSymbols()), self._fst)
+  /* "pywrapfst.pyx":1647
+ *     return _init_FstSymbolTable(syms, self._fst)
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
@@ -19939,11 +19746,11 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_31properties(PyObject *__pyx_v_self,
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_test)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1602, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1647, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1602, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1647, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -19951,12 +19758,12 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_31properties(PyObject *__pyx_v_self,
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1602, __pyx_L3_error)
-    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1602, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1647, __pyx_L3_error)
+    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1647, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1602, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1647, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -19975,7 +19782,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_30properties(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("properties", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_4_Fst_properties(__pyx_v_self, __pyx_v_mask, __pyx_v_test, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1602, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_4_Fst_properties(__pyx_v_self, __pyx_v_mask, __pyx_v_test, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1647, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19992,12 +19799,12 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_30properties(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1622
+/* "pywrapfst.pyx":1667
  *     return self._fst.get().Properties(mask, test)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().Start()
- * 
+ *     """
+ *     start(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_33start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -20014,7 +19821,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1622, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1667, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_33start)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -20029,14 +19836,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1622, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1667, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1622, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1667, __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, 1622, __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, 1667, __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;
@@ -20045,26 +19852,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1623
- * 
- *   cpdef int64 start(self):
+  /* "pywrapfst.pyx":1673
+ *     Returns the start state.
+ *     """
  *     return self._fst.get().Start()             # <<<<<<<<<<<<<<
  * 
  *   cpdef StateIterator states(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1623, __pyx_L1_error)
+    __PYX_ERR(0, 1673, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Start();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1622
+  /* "pywrapfst.pyx":1667
  *     return self._fst.get().Properties(mask, test)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().Start()
- * 
+ *     """
+ *     start(self)
  */
 
   /* function exit code */
@@ -20082,6 +19889,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_33start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_32start[] = "\n    start(self)\n\n    Returns the start state.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_4_Fst_33start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -20099,7 +19907,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32start(struct __pyx_obj_9pywrapfst__
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("start", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_4_Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1622, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_4_Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1667, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20116,7 +19924,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32start(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1625
+/* "pywrapfst.pyx":1675
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -20137,7 +19945,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1625, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1675, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_35states)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -20153,14 +19961,14 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1625, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1675, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1625, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1675, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1625, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1675, __pyx_L1_error)
       __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_2);
       __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20169,7 +19977,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1636
+  /* "pywrapfst.pyx":1686
  *     See also: `arcs`, `mutable_arcs`.
  *     """
  *     return StateIterator(self)             # <<<<<<<<<<<<<<
@@ -20177,19 +19985,19 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
  *   cpdef string text(self, _SymbolTable isymbols=None,
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1636, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1686, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1636, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1686, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1625
+  /* "pywrapfst.pyx":1675
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -20231,7 +20039,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34states(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1625, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1675, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20248,7 +20056,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34states(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1638
+/* "pywrapfst.pyx":1688
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20260,7 +20068,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
 static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_text *__pyx_optional_args) {
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1639
+  /* "pywrapfst.pyx":1689
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -20270,7 +20078,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1640
+  /* "pywrapfst.pyx":1690
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
@@ -20279,7 +20087,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
   bool __pyx_v_acceptor = ((bool)0);
   bool __pyx_v_show_weight_one = ((bool)0);
-  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b_);
+  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b__5);
   fst::SymbolTable *__pyx_v_ssymbols_ptr;
   std::stringstream __pyx_v_sstrm;
   std::string __pyx_r;
@@ -20321,7 +20129,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     }
   }
 
-  /* "pywrapfst.pyx":1638
+  /* "pywrapfst.pyx":1688
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20332,12 +20140,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1638, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1688, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_37text)) {
-      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1638, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1688, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1638, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1688, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -20355,7 +20163,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1638, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1688, __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;
@@ -20365,7 +20173,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1638, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1688, __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;
@@ -20373,7 +20181,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1638, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1688, __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;
@@ -20396,12 +20204,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
         PyTuple_SET_ITEM(__pyx_t_8, 5+__pyx_t_7, __pyx_v_missing_sym);
         __pyx_t_3 = 0;
         __pyx_t_4 = 0;
-        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1638, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1688, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1638, __pyx_L1_error)
+      __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1688, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_9;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20410,7 +20218,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1663
+  /* "pywrapfst.pyx":1713
  *     """
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL             # <<<<<<<<<<<<<<
@@ -20419,7 +20227,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
   __pyx_v_ssymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":1664
+  /* "pywrapfst.pyx":1714
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -20430,7 +20238,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1665
+    /* "pywrapfst.pyx":1715
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:
  *       ssymbols_ptr = ssymbols._table             # <<<<<<<<<<<<<<
@@ -20439,12 +20247,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1665, __pyx_L1_error)
+      __PYX_ERR(0, 1715, __pyx_L1_error)
     }
     __pyx_t_12 = __pyx_v_ssymbols->_table;
     __pyx_v_ssymbols_ptr = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1664
+    /* "pywrapfst.pyx":1714
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef fst.SymbolTable *ssymbols_ptr = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -20453,7 +20261,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
   }
 
-  /* "pywrapfst.pyx":1667
+  /* "pywrapfst.pyx":1717
  *       ssymbols_ptr = ssymbols._table
  *     cdef stringstream sstrm
  *     fst.PrintFst(deref(self._fst), sstrm, "<pywrapfst>",             # <<<<<<<<<<<<<<
@@ -20462,11 +20270,11 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1667, __pyx_L1_error)
+    __PYX_ERR(0, 1717, __pyx_L1_error)
   }
-  __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_pywrapfst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1667, __pyx_L1_error)
+  __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_pywrapfst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1717, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1668
+  /* "pywrapfst.pyx":1718
  *     cdef stringstream sstrm
  *     fst.PrintFst(deref(self._fst), sstrm, "<pywrapfst>",
  *         self._fst.get().InputSymbols() if isymbols is None             # <<<<<<<<<<<<<<
@@ -20477,12 +20285,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   if ((__pyx_t_11 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-      __PYX_ERR(0, 1668, __pyx_L1_error)
+      __PYX_ERR(0, 1718, __pyx_L1_error)
     }
     __pyx_t_13 = __pyx_v_self->_fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1669
+    /* "pywrapfst.pyx":1719
  *     fst.PrintFst(deref(self._fst), sstrm, "<pywrapfst>",
  *         self._fst.get().InputSymbols() if isymbols is None
  *         else isymbols._table,             # <<<<<<<<<<<<<<
@@ -20491,12 +20299,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1669, __pyx_L1_error)
+      __PYX_ERR(0, 1719, __pyx_L1_error)
     }
     __pyx_t_13 = __pyx_v_isymbols->_table;
   }
 
-  /* "pywrapfst.pyx":1670
+  /* "pywrapfst.pyx":1720
  *         self._fst.get().InputSymbols() if isymbols is None
  *         else isymbols._table,
  *         self._fst.get().OutputSymbols() if osymbols is None             # <<<<<<<<<<<<<<
@@ -20507,12 +20315,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   if ((__pyx_t_11 != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-      __PYX_ERR(0, 1670, __pyx_L1_error)
+      __PYX_ERR(0, 1720, __pyx_L1_error)
     }
     __pyx_t_14 = __pyx_v_self->_fst.get()->OutputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1671
+    /* "pywrapfst.pyx":1721
  *         else isymbols._table,
  *         self._fst.get().OutputSymbols() if osymbols is None
  *         else osymbols._table,             # <<<<<<<<<<<<<<
@@ -20521,21 +20329,21 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-      __PYX_ERR(0, 1671, __pyx_L1_error)
+      __PYX_ERR(0, 1721, __pyx_L1_error)
     }
     __pyx_t_14 = __pyx_v_osymbols->_table;
   }
 
-  /* "pywrapfst.pyx":1672
+  /* "pywrapfst.pyx":1722
  *         self._fst.get().OutputSymbols() if osymbols is None
  *         else osymbols._table,
  *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-  __pyx_t_15 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1672, __pyx_L1_error)
+  __pyx_t_15 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1722, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1667
+  /* "pywrapfst.pyx":1717
  *       ssymbols_ptr = ssymbols._table
  *     cdef stringstream sstrm
  *     fst.PrintFst(deref(self._fst), sstrm, "<pywrapfst>",             # <<<<<<<<<<<<<<
@@ -20544,7 +20352,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
  */
   fst::script::PrintFst((*__pyx_v_self->_fst), __pyx_v_sstrm, __pyx_t_9, __pyx_t_13, __pyx_t_14, __pyx_v_ssymbols_ptr, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_15);
 
-  /* "pywrapfst.pyx":1673
+  /* "pywrapfst.pyx":1723
  *         else osymbols._table,
  *         ssymbols_ptr, acceptor, show_weight_one, tostring(missing_sym))
  *     return sstrm.str()             # <<<<<<<<<<<<<<
@@ -20554,7 +20362,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   __pyx_r = __pyx_v_sstrm.str();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1638
+  /* "pywrapfst.pyx":1688
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20595,7 +20403,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
     PyObject* values[6] = {0,0,0,0,0,0};
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1639
+    /* "pywrapfst.pyx":1689
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -20604,7 +20412,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b_);
+    values[5] = ((PyObject *)__pyx_kp_b__5);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -20652,7 +20460,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "text") < 0)) __PYX_ERR(0, 1638, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "text") < 0)) __PYX_ERR(0, 1688, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -20670,10 +20478,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
     if (values[3]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1640, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1690, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1640
+      /* "pywrapfst.pyx":1690
  *   cpdef string text(self, _SymbolTable isymbols=None,
  *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
@@ -20683,7 +20491,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
       __pyx_v_acceptor = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1640, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1690, __pyx_L3_error)
     } else {
       __pyx_v_show_weight_one = ((bool)0);
     }
@@ -20691,18 +20499,18 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_37text(PyObject *__pyx_v_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("text", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1638, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("text", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1688, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1638, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1639, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1639, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1688, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1689, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1689, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4_Fst_36text(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_v_missing_sym);
 
-  /* "pywrapfst.pyx":1638
+  /* "pywrapfst.pyx":1688
  *     return StateIterator(self)
  * 
  *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -20735,7 +20543,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36text(struct __pyx_obj_9pywrapfst__F
   __pyx_t_2.show_weight_one = __pyx_v_show_weight_one;
   __pyx_t_2.missing_sym = __pyx_v_missing_sym;
   __pyx_t_1 = __pyx_vtabptr_9pywrapfst__Fst->text(__pyx_v_self, 1, &__pyx_t_2); 
-  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1638, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1688, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -20752,7 +20560,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36text(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1675
+/* "pywrapfst.pyx":1725
  *     return sstrm.str()
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
@@ -20774,7 +20582,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1675, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1725, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_39verify)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -20789,14 +20597,14 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1675, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1725, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1675, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1725, __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, 1675, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1725, __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;
@@ -20805,7 +20613,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1684
+  /* "pywrapfst.pyx":1734
  *       True if the contents are sane, False otherwise.
  *     """
  *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
@@ -20814,12 +20622,12 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1684, __pyx_L1_error)
+    __PYX_ERR(0, 1734, __pyx_L1_error)
   }
   __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1675
+  /* "pywrapfst.pyx":1725
  *     return sstrm.str()
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
@@ -20860,7 +20668,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38verify(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("verify", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_4_Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1675, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_4_Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1725, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20877,7 +20685,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38verify(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1686
+/* "pywrapfst.pyx":1736
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -20899,7 +20707,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1686, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1736, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_41weight_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -20914,14 +20722,14 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1686, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1736, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1686, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1736, __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, 1686, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1736, __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;
@@ -20930,7 +20738,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1695
+  /* "pywrapfst.pyx":1745
  *       A string representing the weight type.
  *     """
  *     return self._fst.get().WeightType()             # <<<<<<<<<<<<<<
@@ -20939,12 +20747,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1695, __pyx_L1_error)
+    __PYX_ERR(0, 1745, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1686
+  /* "pywrapfst.pyx":1736
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -20984,7 +20792,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40weight_type(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1686, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1736, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21001,7 +20809,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40weight_type(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1697
+/* "pywrapfst.pyx":1747
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -21025,7 +20833,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1697, __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, 1747, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_43write)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -21040,13 +20848,13 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1697, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1747, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1697, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1747, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -21054,19 +20862,19 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1697, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1747, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1697, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1747, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_filename);
           __Pyx_GIVEREF(__pyx_v_filename);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_filename);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1697, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1747, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -21079,7 +20887,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1711
+  /* "pywrapfst.pyx":1761
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -21088,22 +20896,22 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1711, __pyx_L1_error)
+    __PYX_ERR(0, 1761, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1711, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1761, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_t_6) != 0)) != 0);
   if (__pyx_t_7) {
 
-    /* "pywrapfst.pyx":1712
+    /* "pywrapfst.pyx":1762
  *     """
  *     if not self._fst.get().Write(tostring(filename)):
  *       raise FstIOError("Write failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  * 
- *   cpdef string WriteToString(self):
+ *   cpdef string write_to_string(self):
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1712, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1762, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1712, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1762, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -21116,13 +20924,13 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
       }
     }
     if (!__pyx_t_4) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_filename); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1762, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
@@ -21130,19 +20938,19 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_filename};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_3);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __pyx_t_4 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -21159,14 +20967,14 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
       }
     }
     if (!__pyx_t_5) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1712, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __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;
@@ -21175,20 +20983,20 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __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;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL;
         __Pyx_GIVEREF(__pyx_t_3);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_3);
         __pyx_t_3 = 0;
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1712, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -21196,9 +21004,9 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     __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, 1712, __pyx_L1_error)
+    __PYX_ERR(0, 1762, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1711
+    /* "pywrapfst.pyx":1761
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(tostring(filename)):             # <<<<<<<<<<<<<<
@@ -21207,7 +21015,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
  */
   }
 
-  /* "pywrapfst.pyx":1697
+  /* "pywrapfst.pyx":1747
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, filename) except *:             # <<<<<<<<<<<<<<
@@ -21249,8 +21057,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42write(struct __pyx_obj_9pywrapfst__
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_4_Fst_write(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1697, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1697, __pyx_L1_error)
+  __pyx_f_9pywrapfst_4_Fst_write(__pyx_v_self, __pyx_v_filename, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1747, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1747, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21267,16 +21075,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42write(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1714
+/* "pywrapfst.pyx":1764
  *       raise FstIOError("Write failed: {!r}".format(filename))
  * 
- *   cpdef string WriteToString(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().WriteToString()
- * 
+ *   cpdef string write_to_string(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     write_to_string(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45WriteToString(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -21284,14 +21092,14 @@ static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
-  __Pyx_RefNannySetupContext("WriteToString", 0);
+  __Pyx_RefNannySetupContext("write_to_string", 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)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_WriteToString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1714, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1764, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_45WriteToString)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_45write_to_string)) {
       __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))) {
@@ -21304,14 +21112,14 @@ static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1714, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1764, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1714, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1764, __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, 1714, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1764, __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;
@@ -21320,26 +21128,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1715
- * 
- *   cpdef string WriteToString(self):
+  /* "pywrapfst.pyx":1775
+ *     See also: `read_from_string`.
+ *     """
  *     return self._fst.get().WriteToString()             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1715, __pyx_L1_error)
+    __PYX_ERR(0, 1775, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WriteToString();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1714
+  /* "pywrapfst.pyx":1764
  *       raise FstIOError("Write failed: {!r}".format(filename))
  * 
- *   cpdef string WriteToString(self):             # <<<<<<<<<<<<<<
- *     return self._fst.get().WriteToString()
- * 
+ *   cpdef string write_to_string(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     write_to_string(self)
  */
 
   /* function exit code */
@@ -21348,32 +21156,33 @@ static std::string __pyx_f_9pywrapfst_4_Fst_WriteToString(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.WriteToString", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
+  __Pyx_WriteUnraisable("pywrapfst._Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45WriteToString(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45WriteToString(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_4_Fst_44write_to_string[] = "\n    write_to_string(self)\n\n    Serializes FST to a string.\n\n    Returns:\n      A string.\n\n    See also: `read_from_string`.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("WriteToString (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_44WriteToString(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __Pyx_RefNannySetupContext("write_to_string (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_44write_to_string(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_44WriteToString(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("WriteToString", 0);
+  __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_WriteToString(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1714, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_write_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1764, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21382,7 +21191,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44WriteToString(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.WriteToString", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -21390,7 +21199,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44WriteToString(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1728
+/* "pywrapfst.pyx":1788
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -21405,7 +21214,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_check_mutating_imethod", 0);
 
-  /* "pywrapfst.pyx":1733
+  /* "pywrapfst.pyx":1793
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -21414,28 +21223,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1733, __pyx_L1_error)
+    __PYX_ERR(0, 1793, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->__pyx_base._fst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1734
+    /* "pywrapfst.pyx":1794
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1734, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1794, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1734, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1794, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1734, __pyx_L1_error)
+    __PYX_ERR(0, 1794, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1733
+    /* "pywrapfst.pyx":1793
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -21444,7 +21253,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
  */
   }
 
-  /* "pywrapfst.pyx":1728
+  /* "pywrapfst.pyx":1788
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -21462,7 +21271,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1736
+/* "pywrapfst.pyx":1796
  *       raise FstOpError("Operation failed")
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -21477,7 +21286,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_add_arc", 0);
 
-  /* "pywrapfst.pyx":1737
+  /* "pywrapfst.pyx":1797
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -21486,28 +21295,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1737, __pyx_L1_error)
+    __PYX_ERR(0, 1797, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1738
+    /* "pywrapfst.pyx":1798
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1738, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1798, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1738, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1798, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1738, __pyx_L1_error)
+    __PYX_ERR(0, 1798, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1737
+    /* "pywrapfst.pyx":1797
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -21516,7 +21325,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1739
+  /* "pywrapfst.pyx":1799
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -21525,32 +21334,32 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 1739, __pyx_L1_error)
+    __PYX_ERR(0, 1799, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc");
-    __PYX_ERR(0, 1739, __pyx_L1_error)
+    __PYX_ERR(0, 1799, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->AddArc(__pyx_v_state, (*__pyx_v_arc->_arc)) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1740
+    /* "pywrapfst.pyx":1800
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1740, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1800, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1740, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1800, __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, 1740, __pyx_L1_error)
+    __PYX_ERR(0, 1800, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1739
+    /* "pywrapfst.pyx":1799
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -21559,7 +21368,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1741
+  /* "pywrapfst.pyx":1801
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -21568,11 +21377,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1741, __pyx_L1_error)
+    __PYX_ERR(0, 1801, __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, 1741, __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, 1801, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1736
+  /* "pywrapfst.pyx":1796
  *       raise FstOpError("Operation failed")
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -21590,7 +21399,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1743
+/* "pywrapfst.pyx":1803
  *     self._check_mutating_imethod()
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -21627,11 +21436,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_arc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 1743, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 1803, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 1743, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 1803, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -21639,18 +21448,18 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
       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, 1743, __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, 1803, __pyx_L3_error)
     __pyx_v_arc = ((struct __pyx_obj_9pywrapfst_Arc *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1743, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1803, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1743, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1803, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_add_arc(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_arc);
 
   /* function exit code */
@@ -21667,7 +21476,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_arc", 0);
 
-  /* "pywrapfst.pyx":1762
+  /* "pywrapfst.pyx":1822
  *     See also: `add_state`.
  *     """
  *     self._add_arc(state, arc)             # <<<<<<<<<<<<<<
@@ -21676,11 +21485,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_add_arc");
-    __PYX_ERR(0, 1762, __pyx_L1_error)
+    __PYX_ERR(0, 1822, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1762, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1822, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1763
+  /* "pywrapfst.pyx":1823
  *     """
  *     self._add_arc(state, arc)
  *     return self             # <<<<<<<<<<<<<<
@@ -21692,7 +21501,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1743
+  /* "pywrapfst.pyx":1803
  *     self._check_mutating_imethod()
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -21710,7 +21519,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1765
+/* "pywrapfst.pyx":1825
  *     return self
  * 
  *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
@@ -21733,7 +21542,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1765, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1825, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_3add_state)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -21748,14 +21557,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1765, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1825, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1765, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1825, __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, 1765, __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, 1825, __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;
@@ -21764,7 +21573,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":1776
+  /* "pywrapfst.pyx":1836
  *     See also: `add_arc`, `set_start`, `set_final`.
  *     """
  *     cdef int64 result = self._mfst.get().AddState()             # <<<<<<<<<<<<<<
@@ -21773,11 +21582,11 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 1776, __pyx_L1_error)
+    __PYX_ERR(0, 1836, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_mfst.get()->AddState();
 
-  /* "pywrapfst.pyx":1777
+  /* "pywrapfst.pyx":1837
  *     """
  *     cdef int64 result = self._mfst.get().AddState()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -21786,11 +21595,11 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1777, __pyx_L1_error)
+    __PYX_ERR(0, 1837, __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, 1777, __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, 1837, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1778
+  /* "pywrapfst.pyx":1838
  *     cdef int64 result = self._mfst.get().AddState()
  *     self._check_mutating_imethod()
  *     return result             # <<<<<<<<<<<<<<
@@ -21800,7 +21609,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1765
+  /* "pywrapfst.pyx":1825
  *     return self
  * 
  *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
@@ -21842,8 +21651,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("add_state", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_11_MutableFst_add_state(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1765, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1765, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11_MutableFst_add_state(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1825, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1825, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -21860,7 +21669,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1780
+/* "pywrapfst.pyx":1840
  *     return result
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
@@ -21887,27 +21696,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1782
+  /* "pywrapfst.pyx":1842
  *   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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1782, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1842, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v_sort_type_enum)) != 0)) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1783
+    /* "pywrapfst.pyx":1843
  *     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_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1783, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1843, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1783, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1843, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -21920,13 +21729,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_sort_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1783, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_sort_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1843, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_sort_type};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -21934,19 +21743,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_sort_type};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_sort_type);
         __Pyx_GIVEREF(__pyx_v_sort_type);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_sort_type);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -21963,14 +21772,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1843, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -21979,20 +21788,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1843, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -22000,9 +21809,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     __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, 1783, __pyx_L1_error)
+    __PYX_ERR(0, 1843, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1782
+    /* "pywrapfst.pyx":1842
  *   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)):             # <<<<<<<<<<<<<<
@@ -22011,7 +21820,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1784
+  /* "pywrapfst.pyx":1844
  *     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)             # <<<<<<<<<<<<<<
@@ -22020,11 +21829,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1784, __pyx_L1_error)
+    __PYX_ERR(0, 1844, __pyx_L1_error)
   }
   fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v_sort_type_enum);
 
-  /* "pywrapfst.pyx":1785
+  /* "pywrapfst.pyx":1845
  *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
  *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22033,11 +21842,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1785, __pyx_L1_error)
+    __PYX_ERR(0, 1845, __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, 1785, __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, 1845, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1780
+  /* "pywrapfst.pyx":1840
  *     return result
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
@@ -22059,7 +21868,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1787
+/* "pywrapfst.pyx":1847
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22096,7 +21905,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, 1787, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 1847, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22109,7 +21918,7 @@ 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, 1787, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1847, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -22128,7 +21937,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort __pyx_t_1;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":1808
+  /* "pywrapfst.pyx":1868
  *     See also: `topsort`.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -22137,13 +21946,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 '%s'", "_arcsort");
-    __PYX_ERR(0, 1808, __pyx_L1_error)
+    __PYX_ERR(0, 1868, __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, 1808, __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, 1868, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1809
+  /* "pywrapfst.pyx":1869
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -22155,7 +21964,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1787
+  /* "pywrapfst.pyx":1847
  *     self._check_mutating_imethod()
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
@@ -22173,7 +21982,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4arcsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1811
+/* "pywrapfst.pyx":1871
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22191,7 +22000,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1812
+  /* "pywrapfst.pyx":1872
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
@@ -22200,11 +22009,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1812, __pyx_L1_error)
+    __PYX_ERR(0, 1872, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":1813
+  /* "pywrapfst.pyx":1873
  *   cdef void _closure(self, bool closure_plus=False) except *:
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22213,11 +22022,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1813, __pyx_L1_error)
+    __PYX_ERR(0, 1873, __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, 1813, __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, 1873, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1811
+  /* "pywrapfst.pyx":1871
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
@@ -22233,7 +22042,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1815
+/* "pywrapfst.pyx":1875
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22269,7 +22078,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, 1815, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 1875, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22279,14 +22088,14 @@ 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, 1815, __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, 1875, __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, 1815, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1875, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -22305,7 +22114,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure __pyx_t_1;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":1833
+  /* "pywrapfst.pyx":1893
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -22314,13 +22123,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 '%s'", "_closure");
-    __PYX_ERR(0, 1833, __pyx_L1_error)
+    __PYX_ERR(0, 1893, __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, 1833, __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, 1893, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1834
+  /* "pywrapfst.pyx":1894
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
@@ -22332,7 +22141,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1815
+  /* "pywrapfst.pyx":1875
  *     self._check_mutating_imethod()
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -22350,7 +22159,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6closure(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1836
+/* "pywrapfst.pyx":1896
  *     return self
  * 
  *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -22362,7 +22171,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":1837
+  /* "pywrapfst.pyx":1897
  * 
  *   cdef void _concat(self, _Fst ifst) except *:
  *     fst.Concat(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
@@ -22371,15 +22180,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1837, __pyx_L1_error)
+    __PYX_ERR(0, 1897, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 1837, __pyx_L1_error)
+    __PYX_ERR(0, 1897, __pyx_L1_error)
   }
   fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
 
-  /* "pywrapfst.pyx":1838
+  /* "pywrapfst.pyx":1898
  *   cdef void _concat(self, _Fst ifst) except *:
  *     fst.Concat(self._mfst.get(), deref(ifst._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22388,11 +22197,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1838, __pyx_L1_error)
+    __PYX_ERR(0, 1898, __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, 1838, __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, 1898, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1836
+  /* "pywrapfst.pyx":1896
  *     return self
  * 
  *   cdef void _concat(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -22408,7 +22217,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1840
+/* "pywrapfst.pyx":1900
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -22423,7 +22232,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9concat(PyObject *__pyx_v_sel
   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, 1840, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 1900, __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));
 
   /* function exit code */
@@ -22440,7 +22249,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pyw
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":1857
+  /* "pywrapfst.pyx":1917
  *       self.
  *     """
  *     self._concat(ifst)             # <<<<<<<<<<<<<<
@@ -22449,11 +22258,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 '%s'", "_concat");
-    __PYX_ERR(0, 1857, __pyx_L1_error)
+    __PYX_ERR(0, 1917, __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, 1857, __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, 1917, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1858
+  /* "pywrapfst.pyx":1918
  *     """
  *     self._concat(ifst)
  *     return self             # <<<<<<<<<<<<<<
@@ -22465,7 +22274,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1840
+  /* "pywrapfst.pyx":1900
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -22483,7 +22292,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8concat(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1860
+/* "pywrapfst.pyx":1920
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22495,7 +22304,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":1861
+  /* "pywrapfst.pyx":1921
  * 
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -22504,11 +22313,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1861, __pyx_L1_error)
+    __PYX_ERR(0, 1921, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":1862
+  /* "pywrapfst.pyx":1922
  *   cdef void _connect(self) except *:
  *     fst.Connect(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22517,11 +22326,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1862, __pyx_L1_error)
+    __PYX_ERR(0, 1922, __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, 1862, __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, 1922, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1860
+  /* "pywrapfst.pyx":1920
  *     return self
  * 
  *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
@@ -22537,7 +22346,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1864
+/* "pywrapfst.pyx":1924
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22564,7 +22373,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":1876
+  /* "pywrapfst.pyx":1936
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -22573,11 +22382,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 '%s'", "_connect");
-    __PYX_ERR(0, 1876, __pyx_L1_error)
+    __PYX_ERR(0, 1936, __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, 1876, __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, 1936, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1877
+  /* "pywrapfst.pyx":1937
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
@@ -22589,7 +22398,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1864
+  /* "pywrapfst.pyx":1924
  *     self._check_mutating_imethod()
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -22607,7 +22416,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10connect(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1879
+/* "pywrapfst.pyx":1939
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -22619,7 +22428,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":1880
+  /* "pywrapfst.pyx":1940
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:
  *     fst.Decode(self._mfst.get(), deref(encoder._encoder))             # <<<<<<<<<<<<<<
@@ -22628,15 +22437,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1880, __pyx_L1_error)
+    __PYX_ERR(0, 1940, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1880, __pyx_L1_error)
+    __PYX_ERR(0, 1940, __pyx_L1_error)
   }
   fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_encoder->_encoder));
 
-  /* "pywrapfst.pyx":1881
+  /* "pywrapfst.pyx":1941
  *   cdef void _decode(self, EncodeMapper encoder) except *:
  *     fst.Decode(self._mfst.get(), deref(encoder._encoder))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22645,11 +22454,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1881, __pyx_L1_error)
+    __PYX_ERR(0, 1941, __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)
+  ((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, 1941, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1879
+  /* "pywrapfst.pyx":1939
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -22665,7 +22474,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1883
+/* "pywrapfst.pyx":1943
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -22680,7 +22489,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13decode(PyObject *__pyx_v_se
   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, 1883, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 1943, __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));
 
   /* function exit code */
@@ -22697,7 +22506,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":1899
+  /* "pywrapfst.pyx":1959
  *     See also: `encode`.
  *     """
  *     self._decode(encoder)             # <<<<<<<<<<<<<<
@@ -22706,11 +22515,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 '%s'", "_decode");
-    __PYX_ERR(0, 1899, __pyx_L1_error)
+    __PYX_ERR(0, 1959, __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, 1899, __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, 1959, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1900
+  /* "pywrapfst.pyx":1960
  *     """
  *     self._decode(encoder)
  *     return self             # <<<<<<<<<<<<<<
@@ -22722,7 +22531,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1883
+  /* "pywrapfst.pyx":1943
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -22740,7 +22549,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12decode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1902
+/* "pywrapfst.pyx":1962
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -22762,7 +22571,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
   }
 
-  /* "pywrapfst.pyx":1903
+  /* "pywrapfst.pyx":1963
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22772,12 +22581,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 '%s'", "_mfst");
-      __PYX_ERR(0, 1903, __pyx_L1_error)
+      __PYX_ERR(0, 1963, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":1904
+    /* "pywrapfst.pyx":1964
  *   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)):             # <<<<<<<<<<<<<<
@@ -22786,12 +22595,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 '%s'", "_mfst");
-      __PYX_ERR(0, 1904, __pyx_L1_error)
+      __PYX_ERR(0, 1964, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":1903
+  /* "pywrapfst.pyx":1963
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22801,23 +22610,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1905
+    /* "pywrapfst.pyx":1965
  *     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_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1905, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1965, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1905, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1965, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 1905, __pyx_L1_error)
+    __PYX_ERR(0, 1965, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1903
+    /* "pywrapfst.pyx":1963
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -22826,7 +22635,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1906
+  /* "pywrapfst.pyx":1966
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -22835,11 +22644,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1906, __pyx_L1_error)
+    __PYX_ERR(0, 1966, __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, 1906, __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, 1966, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1902
+  /* "pywrapfst.pyx":1962
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -22857,7 +22666,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1908
+/* "pywrapfst.pyx":1968
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -22898,7 +22707,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, 1908, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 1968, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -22908,16 +22717,16 @@ 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, 1908, __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, 1968, __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, 1908, __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, 1968, __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, 1908, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1968, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -22936,7 +22745,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":1928
+  /* "pywrapfst.pyx":1988
  *     See also: `delete_states`.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -22945,13 +22754,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 '%s'", "_delete_arcs");
-    __PYX_ERR(0, 1928, __pyx_L1_error)
+    __PYX_ERR(0, 1988, __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, 1928, __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, 1988, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1929
+  /* "pywrapfst.pyx":1989
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -22963,7 +22772,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1908
+  /* "pywrapfst.pyx":1968
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -22981,7 +22790,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14delete_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1931
+/* "pywrapfst.pyx":1991
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23003,17 +22812,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":1933
+  /* "pywrapfst.pyx":1993
  *   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, 1933, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 1993, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":1934
+    /* "pywrapfst.pyx":1994
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23022,29 +22831,29 @@ 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 '%s'", "_mfst");
-      __PYX_ERR(0, 1934, __pyx_L1_error)
+      __PYX_ERR(0, 1994, __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, 1934, __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, 1994, __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 (__pyx_t_1) {
 
-      /* "pywrapfst.pyx":1935
+      /* "pywrapfst.pyx":1995
  *     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_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1935, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1995, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1935, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1995, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_Raise(__pyx_t_4, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __PYX_ERR(0, 1935, __pyx_L1_error)
+      __PYX_ERR(0, 1995, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":1934
+      /* "pywrapfst.pyx":1994
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -23053,7 +22862,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
     }
 
-    /* "pywrapfst.pyx":1933
+    /* "pywrapfst.pyx":1993
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -23063,7 +22872,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":1937
+  /* "pywrapfst.pyx":1997
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -23073,13 +22882,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 '%s'", "_mfst");
-      __PYX_ERR(0, 1937, __pyx_L1_error)
+      __PYX_ERR(0, 1997, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":1938
+  /* "pywrapfst.pyx":1998
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23088,11 +22897,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1938, __pyx_L1_error)
+    __PYX_ERR(0, 1998, __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, 1938, __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, 1998, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1931
+  /* "pywrapfst.pyx":1991
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -23110,7 +22919,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1940
+/* "pywrapfst.pyx":2000
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23147,7 +22956,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, 1940, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2000, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23160,7 +22969,7 @@ 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, 1940, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2000, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23179,7 +22988,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":1958
+  /* "pywrapfst.pyx":2018
  *     See also: `delete_arcs`.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
@@ -23188,13 +22997,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 '%s'", "_delete_states");
-    __PYX_ERR(0, 1958, __pyx_L1_error)
+    __PYX_ERR(0, 2018, __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, 1958, __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, 2018, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1959
+  /* "pywrapfst.pyx":2019
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
@@ -23206,7 +23015,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1940
+  /* "pywrapfst.pyx":2000
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -23224,7 +23033,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1961
+/* "pywrapfst.pyx":2021
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -23236,7 +23045,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":1962
+  /* "pywrapfst.pyx":2022
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:
  *     fst.Encode(self._mfst.get(), encoder._encoder.get())             # <<<<<<<<<<<<<<
@@ -23245,15 +23054,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1962, __pyx_L1_error)
+    __PYX_ERR(0, 2022, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_encoder) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_encoder");
-    __PYX_ERR(0, 1962, __pyx_L1_error)
+    __PYX_ERR(0, 2022, __pyx_L1_error)
   }
   fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_encoder->_encoder.get());
 
-  /* "pywrapfst.pyx":1963
+  /* "pywrapfst.pyx":2023
  *   cdef void _encode(self, EncodeMapper encoder) except *:
  *     fst.Encode(self._mfst.get(), encoder._encoder.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23262,11 +23071,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1963, __pyx_L1_error)
+    __PYX_ERR(0, 2023, __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, 2023, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1961
+  /* "pywrapfst.pyx":2021
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper encoder) except *:             # <<<<<<<<<<<<<<
@@ -23282,7 +23091,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1965
+/* "pywrapfst.pyx":2025
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -23297,7 +23106,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19encode(PyObject *__pyx_v_se
   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, 1965, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_encoder), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "encoder", 0))) __PYX_ERR(0, 2025, __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));
 
   /* function exit code */
@@ -23314,7 +23123,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":1986
+  /* "pywrapfst.pyx":2046
  *     See also: `decode`.
  *     """
  *     self._encode(encoder)             # <<<<<<<<<<<<<<
@@ -23323,11 +23132,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 '%s'", "_encode");
-    __PYX_ERR(0, 1986, __pyx_L1_error)
+    __PYX_ERR(0, 2046, __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, 1986, __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, 2046, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1987
+  /* "pywrapfst.pyx":2047
  *     """
  *     self._encode(encoder)
  *     return self             # <<<<<<<<<<<<<<
@@ -23339,7 +23148,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1965
+  /* "pywrapfst.pyx":2025
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper encoder):             # <<<<<<<<<<<<<<
@@ -23357,7 +23166,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18encode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1989
+/* "pywrapfst.pyx":2049
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23369,7 +23178,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":1990
+  /* "pywrapfst.pyx":2050
  * 
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -23378,11 +23187,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 '%s'", "_mfst");
-    __PYX_ERR(0, 1990, __pyx_L1_error)
+    __PYX_ERR(0, 2050, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":1991
+  /* "pywrapfst.pyx":2051
  *   cdef void _invert(self) except *:
  *     fst.Invert(self._mfst.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23391,11 +23200,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1991, __pyx_L1_error)
+    __PYX_ERR(0, 2051, __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, 1991, __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, 2051, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1989
+  /* "pywrapfst.pyx":2049
  *     return self
  * 
  *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
@@ -23411,7 +23220,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1993
+/* "pywrapfst.pyx":2053
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23438,7 +23247,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2005
+  /* "pywrapfst.pyx":2065
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -23447,11 +23256,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 '%s'", "_invert");
-    __PYX_ERR(0, 2005, __pyx_L1_error)
+    __PYX_ERR(0, 2065, __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, 2005, __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, 2065, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2006
+  /* "pywrapfst.pyx":2066
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
@@ -23463,7 +23272,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1993
+  /* "pywrapfst.pyx":2053
  *     self._check_mutating_imethod()
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -23481,7 +23290,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20invert(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2008
+/* "pywrapfst.pyx":2068
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -23490,9 +23299,9 @@ 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;
+  float __pyx_v_delta = __pyx_k__15;
 
-  /* "pywrapfst.pyx":2009
+  /* "pywrapfst.pyx":2069
  * 
  *   cdef void _minimize(self, float delta=fst.kDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
@@ -23511,7 +23320,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2011
+  /* "pywrapfst.pyx":2071
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -23520,11 +23329,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2011, __pyx_L1_error)
+    __PYX_ERR(0, 2071, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2012
+  /* "pywrapfst.pyx":2072
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23533,11 +23342,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2012, __pyx_L1_error)
+    __PYX_ERR(0, 2072, __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, 2012, __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, 2072, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2008
+  /* "pywrapfst.pyx":2068
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kDelta,             # <<<<<<<<<<<<<<
@@ -23553,7 +23362,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2014
+/* "pywrapfst.pyx":2074
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -23596,7 +23405,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, 2014, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2074, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23607,19 +23416,19 @@ 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, 2014, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2074, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__12;
+      __pyx_v_delta = __pyx_k__16;
     }
     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, 2014, __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, 2074, __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, 2014, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2074, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23638,7 +23447,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize __pyx_t_1;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2040
+  /* "pywrapfst.pyx":2100
  *       self.
  *     """
  *     self._minimize(delta)             # <<<<<<<<<<<<<<
@@ -23647,13 +23456,13 @@ 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 '%s'", "_minimize");
-    __PYX_ERR(0, 2040, __pyx_L1_error)
+    __PYX_ERR(0, 2100, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.delta = __pyx_v_delta;
-  ((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, 2040, __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, 2100, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2041
+  /* "pywrapfst.pyx":2101
  *     """
  *     self._minimize(delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -23665,7 +23474,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2014
+  /* "pywrapfst.pyx":2074
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -23683,7 +23492,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22minimize(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2043
+/* "pywrapfst.pyx":2103
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -23706,11 +23515,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2043, __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, 2103, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_25mutable_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, 2043, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2103, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -23724,14 +23533,14 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2043, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2103, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2043, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2103, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -23740,26 +23549,26 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2043, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2103, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2043, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2103, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2043, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2103, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
       }
       __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, 2043, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2103, __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;
@@ -23768,7 +23577,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2058
+  /* "pywrapfst.pyx":2117
  *     See also: `arcs`, `states`.
  *     """
  *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -23776,9 +23585,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, 2058, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2058, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -23786,14 +23595,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, 2058, __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, 2117, __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":2043
+  /* "pywrapfst.pyx":2103
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -23819,14 +23628,14 @@ 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 iterator over arcs leaving some state which supports\n    arc mutation.\n\n    Args:\n      s: The source state ID.\n\n    Returns:\n      A MutableArcIterator over arcs leaving state `s`.\n\n    See also: `arcs`, `states`.\n    ";
+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) {
   __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, 2043, __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, 2103, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -23847,7 +23656,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_o
   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, 2043, __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, 2103, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23864,16 +23673,17 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24mutable_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2060
+/* "pywrapfst.pyx":2119
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
- *     if tst == NULL:
+ *     """
+ *     mutable_input_symbols(self)
  */
 
 /* 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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -23893,21 +23703,21 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2061
- * 
- *   def mutable_input_symbols(self):
+  /* "pywrapfst.pyx":2125
+ *     Returns the FST's (mutable) input symbol table, or None if none is present.
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()             # <<<<<<<<<<<<<<
  *     if tst == NULL:
  *       return
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2061, __pyx_L1_error)
+    __PYX_ERR(0, 2125, __pyx_L1_error)
   }
   __pyx_v_tst = __pyx_v_self->_mfst.get()->MutableInputSymbols();
 
-  /* "pywrapfst.pyx":2062
- *   def mutable_input_symbols(self):
+  /* "pywrapfst.pyx":2126
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
  *     if tst == NULL:             # <<<<<<<<<<<<<<
  *       return
@@ -23916,7 +23726,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   __pyx_t_1 = ((__pyx_v_tst == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2063
+    /* "pywrapfst.pyx":2127
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
  *     if tst == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -23927,8 +23737,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2062
- *   def mutable_input_symbols(self):
+    /* "pywrapfst.pyx":2126
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
  *     if tst == NULL:             # <<<<<<<<<<<<<<
  *       return
@@ -23936,7 +23746,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
  */
   }
 
-  /* "pywrapfst.pyx":2064
+  /* "pywrapfst.pyx":2128
  *     if tst == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(tst, self._mfst)             # <<<<<<<<<<<<<<
@@ -23946,20 +23756,20 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2064, __pyx_L1_error)
+    __PYX_ERR(0, 2128, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_tst, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2064, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_tst, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2128, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2060
+  /* "pywrapfst.pyx":2119
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
- *     if tst == NULL:
+ *     """
+ *     mutable_input_symbols(self)
  */
 
   /* function exit code */
@@ -23973,16 +23783,17 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_input_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2066
+/* "pywrapfst.pyx":2130
  *     return _init_MutableFstSymbolTable(tst, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
- *     if tst == NULL:
+ *     """
+ *     mutable_output_symbols(self)
  */
 
 /* 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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -24002,21 +23813,21 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2067
- * 
- *   def mutable_output_symbols(self):
+  /* "pywrapfst.pyx":2136
+ *     Returns the FST's (mutable) output symbol table, or None if none is present.
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
  *     if tst == NULL:
  *       return
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2067, __pyx_L1_error)
+    __PYX_ERR(0, 2136, __pyx_L1_error)
   }
   __pyx_v_tst = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
 
-  /* "pywrapfst.pyx":2068
- *   def mutable_output_symbols(self):
+  /* "pywrapfst.pyx":2137
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
  *     if tst == NULL:             # <<<<<<<<<<<<<<
  *       return
@@ -24025,7 +23836,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   __pyx_t_1 = ((__pyx_v_tst == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2069
+    /* "pywrapfst.pyx":2138
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
  *     if tst == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -24036,8 +23847,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2068
- *   def mutable_output_symbols(self):
+    /* "pywrapfst.pyx":2137
+ *     """
  *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
  *     if tst == NULL:             # <<<<<<<<<<<<<<
  *       return
@@ -24045,7 +23856,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
  */
   }
 
-  /* "pywrapfst.pyx":2070
+  /* "pywrapfst.pyx":2139
  *     if tst == NULL:
  *       return
  *     return _init_MutableFstSymbolTable(tst, self._mfst)             # <<<<<<<<<<<<<<
@@ -24055,20 +23866,20 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2070, __pyx_L1_error)
+    __PYX_ERR(0, 2139, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_tst, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2070, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_tst, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2066
+  /* "pywrapfst.pyx":2130
  *     return _init_MutableFstSymbolTable(tst, self._mfst)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
- *     if tst == NULL:
+ *     """
+ *     mutable_output_symbols(self)
  */
 
   /* function exit code */
@@ -24082,12 +23893,12 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_output_symbols(stru
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2072
+/* "pywrapfst.pyx":2141
  *     return _init_MutableFstSymbolTable(tst, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
- *     return self._mfst.get().NumStates()
- * 
+ *     """
+ *     num_states(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -24104,7 +23915,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2072, __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, 2141, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_31num_states)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -24119,14 +23930,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2072, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2141, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2072, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2141, __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, 2072, __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, 2141, __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;
@@ -24135,26 +23946,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2073
- * 
- *   cpdef int64 num_states(self):
+  /* "pywrapfst.pyx":2147
+ *     Returns the number of states.
+ *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
  * 
  *   cdef void _project(self, bool project_output=False) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2073, __pyx_L1_error)
+    __PYX_ERR(0, 2147, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2072
+  /* "pywrapfst.pyx":2141
  *     return _init_MutableFstSymbolTable(tst, self._mfst)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
- *     return self._mfst.get().NumStates()
- * 
+ *     """
+ *     num_states(self)
  */
 
   /* function exit code */
@@ -24172,6 +23983,7 @@ 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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -24189,7 +24001,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30num_states(struct __pyx_obj
   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, 2072, __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, 2141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -24206,7 +24018,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30num_states(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2075
+/* "pywrapfst.pyx":2149
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24224,7 +24036,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2076
+  /* "pywrapfst.pyx":2150
  * 
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))             # <<<<<<<<<<<<<<
@@ -24233,11 +24045,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2076, __pyx_L1_error)
+    __PYX_ERR(0, 2150, __pyx_L1_error)
   }
   fst::script::Project(__pyx_v_self->_mfst.get(), fst::script::GetProjectType(__pyx_v_project_output));
 
-  /* "pywrapfst.pyx":2077
+  /* "pywrapfst.pyx":2151
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24246,11 +24058,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2077, __pyx_L1_error)
+    __PYX_ERR(0, 2151, __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, 2077, __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, 2151, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2075
+  /* "pywrapfst.pyx":2149
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
@@ -24266,7 +24078,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2079
+/* "pywrapfst.pyx":2153
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24302,7 +24114,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, 2079, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2153, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24312,14 +24124,14 @@ 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, 2079, __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, 2153, __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, 2079, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("project", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2153, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24338,7 +24150,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__project __pyx_t_1;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2097
+  /* "pywrapfst.pyx":2171
  *     See also: `decode`, `encode`, `relabel_pairs`, `relabel_symbols`.
  *     """
  *     self._project(project_output)             # <<<<<<<<<<<<<<
@@ -24347,13 +24159,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 '%s'", "_project");
-    __PYX_ERR(0, 2097, __pyx_L1_error)
+    __PYX_ERR(0, 2171, __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, 2097, __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, 2171, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2098
+  /* "pywrapfst.pyx":2172
  *     """
  *     self._project(project_output)
  *     return self             # <<<<<<<<<<<<<<
@@ -24365,7 +24177,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2079
+  /* "pywrapfst.pyx":2153
  *     self._check_mutating_imethod()
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
@@ -24383,7 +24195,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2100
+/* "pywrapfst.pyx":2174
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24392,10 +24204,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32project(struct __pyx_obj_9p
  */
 
 static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__13;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__14;
+  float __pyx_v_delta = __pyx_k__17;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__18;
 
-  /* "pywrapfst.pyx":2101
+  /* "pywrapfst.pyx":2175
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:             # <<<<<<<<<<<<<<
@@ -24419,7 +24231,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
     }
   }
 
-  /* "pywrapfst.pyx":2103
+  /* "pywrapfst.pyx":2177
  *                    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(),             # <<<<<<<<<<<<<<
@@ -24428,20 +24240,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 '%s'", "weight_type");
-    __PYX_ERR(0, 2103, __pyx_L1_error)
+    __PYX_ERR(0, 2177, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2104
+  /* "pywrapfst.pyx":2178
  *     # 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, 2103, __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, 2177, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2105
+  /* "pywrapfst.pyx":2179
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -24450,11 +24262,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2105, __pyx_L1_error)
+    __PYX_ERR(0, 2179, __pyx_L1_error)
   }
   fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2106
+  /* "pywrapfst.pyx":2180
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24463,11 +24275,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2106, __pyx_L1_error)
+    __PYX_ERR(0, 2180, __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)
+  ((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, 2180, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2100
+  /* "pywrapfst.pyx":2174
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
@@ -24483,7 +24295,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2108
+/* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24505,7 +24317,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":2111
+    /* "pywrapfst.pyx":2185
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -24542,7 +24354,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, 2108, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2182, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24554,20 +24366,20 @@ 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, 2109, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2183, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__15;
+      __pyx_v_delta = __pyx_k__19;
     }
     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, 2110, __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, 2184, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__16;
+      __pyx_v_nstate = __pyx_k__20;
     }
     __pyx_v_weight = values[2];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2108, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2182, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24575,7 +24387,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35prune(PyObject *__pyx_v_sel
   __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);
 
-  /* "pywrapfst.pyx":2108
+  /* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24594,7 +24406,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune __pyx_t_1;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2133
+  /* "pywrapfst.pyx":2207
  *     See also: The constructive variant.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -24603,15 +24415,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 '%s'", "_prune");
-    __PYX_ERR(0, 2133, __pyx_L1_error)
+    __PYX_ERR(0, 2207, __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, 2133, __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, 2207, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2134
+  /* "pywrapfst.pyx":2208
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -24623,7 +24435,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2108
+  /* "pywrapfst.pyx":2182
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -24641,7 +24453,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34prune(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2136
+/* "pywrapfst.pyx":2210
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -24650,9 +24462,9 @@ 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;
+  float __pyx_v_delta = __pyx_k__21;
 
-  /* "pywrapfst.pyx":2138
+  /* "pywrapfst.pyx":2212
  *   cdef void _push(self,
  *                   float delta=fst.kDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -24661,7 +24473,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2139
+  /* "pywrapfst.pyx":2213
  *                   float delta=fst.kDelta,
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -24683,7 +24495,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
     }
   }
 
-  /* "pywrapfst.pyx":2140
+  /* "pywrapfst.pyx":2214
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,             # <<<<<<<<<<<<<<
@@ -24692,10 +24504,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2140, __pyx_L1_error)
+    __PYX_ERR(0, 2214, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2141
+  /* "pywrapfst.pyx":2215
  *                   bool to_final=False) except *:
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
@@ -24704,7 +24516,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":2142
+  /* "pywrapfst.pyx":2216
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24713,11 +24525,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2142, __pyx_L1_error)
+    __PYX_ERR(0, 2216, __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, 2142, __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, 2216, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2136
+  /* "pywrapfst.pyx":2210
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -24733,7 +24545,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2144
+/* "pywrapfst.pyx":2218
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -24783,7 +24595,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, 2144, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2218, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24795,15 +24607,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, 2145, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2219, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__18;
+      __pyx_v_delta = __pyx_k__22;
     }
     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, 2146, __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, 2220, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2146
+      /* "pywrapfst.pyx":2220
  *   def push(self,
  *            float delta=fst.kDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -24813,10 +24625,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, 2147, __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, 2221, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2147
+      /* "pywrapfst.pyx":2221
  *            float delta=fst.kDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
@@ -24828,7 +24640,7 @@ 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, 2144, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2218, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24836,7 +24648,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37push(PyObject *__pyx_v_self
   __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);
 
-  /* "pywrapfst.pyx":2144
+  /* "pywrapfst.pyx":2218
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -24855,7 +24667,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__push __pyx_t_1;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2173
+  /* "pywrapfst.pyx":2247
  *     See also: The constructive variant, which also supports label pushing.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
@@ -24864,15 +24676,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 '%s'", "_push");
-    __PYX_ERR(0, 2173, __pyx_L1_error)
+    __PYX_ERR(0, 2247, __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, 2173, __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, 2247, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2174
+  /* "pywrapfst.pyx":2248
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -24884,7 +24696,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2144
+  /* "pywrapfst.pyx":2218
  *     self._check_mutating_imethod()
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -24902,7 +24714,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36push(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2176
+/* "pywrapfst.pyx":2250
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -24942,7 +24754,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2178
+  /* "pywrapfst.pyx":2252
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:
  *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
  *     _ipairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -24953,11 +24765,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, 2178, __pyx_L1_error)
+    __PYX_ERR(0, 2252, __pyx_L1_error)
   }
   __pyx_v__ipairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2180
+  /* "pywrapfst.pyx":2254
  *     _ipairs.reset(new vector[fst.LabelPair]())
  *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
  *     _opairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -24968,21 +24780,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, 2180, __pyx_L1_error)
+    __PYX_ERR(0, 2254, __pyx_L1_error)
   }
   __pyx_v__opairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2183
+  /* "pywrapfst.pyx":2257
  *     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, 2183, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2257, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2184
+    /* "pywrapfst.pyx":2258
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -24993,26 +24805,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, 2184, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2258, __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, 2184, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2258, __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, 2184, __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, 2258, __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, 2184, __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, 2258, __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, 2184, __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, 2258, __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, 2184, __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, 2258, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25022,7 +24834,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2184, __pyx_L1_error)
+            else __PYX_ERR(0, 2258, __pyx_L1_error)
           }
           break;
         }
@@ -25038,7 +24850,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, 2184, __pyx_L1_error)
+          __PYX_ERR(0, 2258, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25051,15 +24863,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, 2184, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2258, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2184, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2258, __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, 2184, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2258, __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;
@@ -25067,7 +24879,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, 2184, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2258, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L7_unpacking_done;
@@ -25075,17 +24887,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, 2184, __pyx_L1_error)
+        __PYX_ERR(0, 2258, __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, 2184, __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, 2258, __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, 2184, __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, 2258, __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":2185
+      /* "pywrapfst.pyx":2259
  *     if ipairs:
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -25096,16 +24908,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, 2185, __pyx_L1_error)
+        __PYX_ERR(0, 2259, __pyx_L1_error)
       }
       try {
         __pyx_v__ipairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2185, __pyx_L1_error)
+        __PYX_ERR(0, 2259, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2184
+      /* "pywrapfst.pyx":2258
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -25115,7 +24927,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":2183
+    /* "pywrapfst.pyx":2257
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
@@ -25124,17 +24936,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2186
+  /* "pywrapfst.pyx":2260
  *       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, 2186, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2260, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2187
+    /* "pywrapfst.pyx":2261
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25145,26 +24957,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, 2187, __pyx_L1_error)
+      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2261, __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, 2187, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2261, __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, 2187, __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, 2261, __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, 2187, __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, 2261, __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, 2187, __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, 2261, __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, 2187, __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, 2261, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           #endif
         }
@@ -25174,7 +24986,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2187, __pyx_L1_error)
+            else __PYX_ERR(0, 2261, __pyx_L1_error)
           }
           break;
         }
@@ -25190,7 +25002,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, 2187, __pyx_L1_error)
+          __PYX_ERR(0, 2261, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -25203,15 +25015,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, 2187, __pyx_L1_error)
+        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2261, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2187, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2261, __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, 2187, __pyx_L1_error)
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2261, __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;
@@ -25219,7 +25031,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, 2187, __pyx_L1_error)
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2261, __pyx_L1_error)
         __pyx_t_10 = NULL;
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         goto __pyx_L12_unpacking_done;
@@ -25227,17 +25039,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, 2187, __pyx_L1_error)
+        __PYX_ERR(0, 2261, __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, 2187, __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, 2261, __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, 2187, __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, 2261, __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":2188
+      /* "pywrapfst.pyx":2262
  *     if opairs:
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -25248,16 +25060,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, 2188, __pyx_L1_error)
+        __PYX_ERR(0, 2262, __pyx_L1_error)
       }
       try {
         __pyx_v__opairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2188, __pyx_L1_error)
+        __PYX_ERR(0, 2262, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2187
+      /* "pywrapfst.pyx":2261
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -25267,7 +25079,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":2186
+    /* "pywrapfst.pyx":2260
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
@@ -25276,7 +25088,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2189
+  /* "pywrapfst.pyx":2263
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -25294,23 +25106,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __pyx_L14_bool_binop_done:;
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2190
+    /* "pywrapfst.pyx":2264
  *         _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_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2190, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2264, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2190, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2264, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_6, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __PYX_ERR(0, 2190, __pyx_L1_error)
+    __PYX_ERR(0, 2264, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2189
+    /* "pywrapfst.pyx":2263
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -25319,7 +25131,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2191
+  /* "pywrapfst.pyx":2265
  *     if _ipairs.get().empty() and _opairs.get().empty():
  *       raise FstArgError("No relabeling pairs specified.")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))             # <<<<<<<<<<<<<<
@@ -25328,11 +25140,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2191, __pyx_L1_error)
+    __PYX_ERR(0, 2265, __pyx_L1_error)
   }
   fst::script::Relabel(__pyx_v_self->_mfst.get(), (*__pyx_v__ipairs), (*__pyx_v__opairs));
 
-  /* "pywrapfst.pyx":2192
+  /* "pywrapfst.pyx":2266
  *       raise FstArgError("No relabeling pairs specified.")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25341,11 +25153,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2192, __pyx_L1_error)
+    __PYX_ERR(0, 2266, __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, 2192, __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, 2266, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2176
+  /* "pywrapfst.pyx":2250
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -25366,7 +25178,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2194
+/* "pywrapfst.pyx":2268
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25411,7 +25223,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, 2194, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2268, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25426,7 +25238,7 @@ 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, 2194, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2268, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -25445,7 +25257,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2216
+  /* "pywrapfst.pyx":2290
  *     See also: `decode`, `encode`, `project`, `relabel_tables`.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
@@ -25454,14 +25266,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 '%s'", "_relabel_pairs");
-    __PYX_ERR(0, 2216, __pyx_L1_error)
+    __PYX_ERR(0, 2290, __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, 2216, __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, 2290, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2217
+  /* "pywrapfst.pyx":2291
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -25473,7 +25285,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2194
+  /* "pywrapfst.pyx":2268
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -25491,7 +25303,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38relabel_pairs(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2219
+/* "pywrapfst.pyx":2293
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -25501,7 +25313,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":2220
+  /* "pywrapfst.pyx":2294
  * 
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25510,7 +25322,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":2221
+  /* "pywrapfst.pyx":2295
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,
  *                             _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25518,9 +25330,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  *                             bool attach_new_isymbols=True,
  */
   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_);
+  PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_b__5);
 
-  /* "pywrapfst.pyx":2223
+  /* "pywrapfst.pyx":2297
  *                             _SymbolTable new_isymbols=None,
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -25529,7 +25341,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2224
+  /* "pywrapfst.pyx":2298
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25538,7 +25350,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":2225
+  /* "pywrapfst.pyx":2299
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,
  *                             _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25546,9 +25358,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  *                             bool attach_new_osymbols=True) except *:
  */
   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_);
+  PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_b__5);
 
-  /* "pywrapfst.pyx":2227
+  /* "pywrapfst.pyx":2301
  *                             _SymbolTable new_osymbols=None,
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
@@ -25597,7 +25409,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
   }
 
-  /* "pywrapfst.pyx":2228
+  /* "pywrapfst.pyx":2302
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -25617,23 +25429,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2229
+    /* "pywrapfst.pyx":2303
  *                             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_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2229, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2303, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2229, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2303, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_5, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __PYX_ERR(0, 2229, __pyx_L1_error)
+    __PYX_ERR(0, 2303, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2228
+    /* "pywrapfst.pyx":2302
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -25642,7 +25454,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2230
+  /* "pywrapfst.pyx":2304
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL             # <<<<<<<<<<<<<<
@@ -25651,7 +25463,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   __pyx_v_new_isymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":2231
+  /* "pywrapfst.pyx":2305
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -25662,7 +25474,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":2232
+    /* "pywrapfst.pyx":2306
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:
  *       new_isymbols_ptr = new_isymbols._table             # <<<<<<<<<<<<<<
@@ -25671,12 +25483,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 '%s'", "_table");
-      __PYX_ERR(0, 2232, __pyx_L1_error)
+      __PYX_ERR(0, 2306, __pyx_L1_error)
     }
     __pyx_t_6 = __pyx_v_new_isymbols->_table;
     __pyx_v_new_isymbols_ptr = __pyx_t_6;
 
-    /* "pywrapfst.pyx":2231
+    /* "pywrapfst.pyx":2305
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef fst.SymbolTable *new_isymbols_ptr = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -25685,7 +25497,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2233
+  /* "pywrapfst.pyx":2307
  *     if new_isymbols is not None:
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL             # <<<<<<<<<<<<<<
@@ -25694,7 +25506,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   __pyx_v_new_osymbols_ptr = NULL;
 
-  /* "pywrapfst.pyx":2234
+  /* "pywrapfst.pyx":2308
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -25705,7 +25517,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":2235
+    /* "pywrapfst.pyx":2309
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table             # <<<<<<<<<<<<<<
@@ -25714,12 +25526,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 '%s'", "_table");
-      __PYX_ERR(0, 2235, __pyx_L1_error)
+      __PYX_ERR(0, 2309, __pyx_L1_error)
     }
     __pyx_t_6 = __pyx_v_new_osymbols->_table;
     __pyx_v_new_osymbols_ptr = __pyx_t_6;
 
-    /* "pywrapfst.pyx":2234
+    /* "pywrapfst.pyx":2308
  *       new_isymbols_ptr = new_isymbols._table
  *     cdef fst.SymbolTable *new_osymbols_ptr = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -25728,7 +25540,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2236
+  /* "pywrapfst.pyx":2310
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -25737,10 +25549,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2236, __pyx_L1_error)
+    __PYX_ERR(0, 2310, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2237
+  /* "pywrapfst.pyx":2311
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),
  *         self._fst.get().InputSymbols() if old_isymbols is None else             # <<<<<<<<<<<<<<
@@ -25751,12 +25563,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 '%s'", "_fst");
-      __PYX_ERR(0, 2237, __pyx_L1_error)
+      __PYX_ERR(0, 2311, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":2238
+    /* "pywrapfst.pyx":2312
  *     fst.Relabel(self._mfst.get(),
  *         self._fst.get().InputSymbols() if old_isymbols is None else
  *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
@@ -25765,13 +25577,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 '%s'", "_table");
-      __PYX_ERR(0, 2238, __pyx_L1_error)
+      __PYX_ERR(0, 2312, __pyx_L1_error)
     }
     __pyx_t_7 = __pyx_v_old_isymbols->_table;
   }
-  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2238, __pyx_L1_error)
+  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2312, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2240
+  /* "pywrapfst.pyx":2314
  *         old_isymbols._table, new_isymbols_ptr, tostring(unknown_isymbol),
  *         attach_new_isymbols,
  *         self._fst.get().OutputSymbols() if old_osymbols is None else             # <<<<<<<<<<<<<<
@@ -25782,12 +25594,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 '%s'", "_fst");
-      __PYX_ERR(0, 2240, __pyx_L1_error)
+      __PYX_ERR(0, 2314, __pyx_L1_error)
     }
     __pyx_t_9 = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":2241
+    /* "pywrapfst.pyx":2315
  *         attach_new_isymbols,
  *         self._fst.get().OutputSymbols() if old_osymbols is None else
  *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
@@ -25796,13 +25608,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 '%s'", "_table");
-      __PYX_ERR(0, 2241, __pyx_L1_error)
+      __PYX_ERR(0, 2315, __pyx_L1_error)
     }
     __pyx_t_9 = __pyx_v_old_osymbols->_table;
   }
-  __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2241, __pyx_L1_error)
+  __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2315, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2236
+  /* "pywrapfst.pyx":2310
  *     if new_osymbols is not None:
  *       new_osymbols_ptr = new_osymbols._table
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -25811,7 +25623,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_t_7, __pyx_v_new_isymbols_ptr, __pyx_t_8, __pyx_v_attach_new_isymbols, __pyx_t_9, __pyx_v_new_osymbols_ptr, __pyx_t_10, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2243
+  /* "pywrapfst.pyx":2317
  *         old_osymbols._table, new_osymbols_ptr, tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25820,11 +25632,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2243, __pyx_L1_error)
+    __PYX_ERR(0, 2317, __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, 2243, __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, 2317, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2219
+  /* "pywrapfst.pyx":2293
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -25842,7 +25654,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2245
+/* "pywrapfst.pyx":2319
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -25869,7 +25681,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":2246
+    /* "pywrapfst.pyx":2320
  * 
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25878,7 +25690,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  */
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2247
+    /* "pywrapfst.pyx":2321
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,
  *                      _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -25886,9 +25698,9 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  *                      bool attach_new_isymbols=True,
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[2] = ((PyObject *)__pyx_kp_b_);
+    values[2] = ((PyObject *)__pyx_kp_b__5);
 
-    /* "pywrapfst.pyx":2250
+    /* "pywrapfst.pyx":2324
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25897,7 +25709,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  */
     values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2251
+    /* "pywrapfst.pyx":2325
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,
  *                      _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -25905,7 +25717,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_tables(PyObject *__
  *                      bool attach_new_osymbols=True):
  */
     values[5] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[6] = ((PyObject *)__pyx_kp_b_);
+    values[6] = ((PyObject *)__pyx_kp_b__5);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -25965,7 +25777,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, 2245, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2319, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25985,10 +25797,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, 2249, __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, 2323, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2249
+      /* "pywrapfst.pyx":2323
  *                      _SymbolTable new_isymbols=None,
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -26001,10 +25813,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, 2253, __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, 2327, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2253
+      /* "pywrapfst.pyx":2327
  *                      _SymbolTable new_osymbols=None,
  *                      unknown_osymbol=b"",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
@@ -26016,19 +25828,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, 2245, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2319, __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, 2246, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2247, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2250, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2251, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_isymbols", 0))) __PYX_ERR(0, 2320, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2321, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2324, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2325, __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);
 
-  /* "pywrapfst.pyx":2245
+  /* "pywrapfst.pyx":2319
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26051,7 +25863,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2289
+  /* "pywrapfst.pyx":2363
  *     See also: `decode`, `encode`, `project`, `relabel_pairs`.
  *     """
  *     self._relabel_tables(old_isymbols, new_isymbols,             # <<<<<<<<<<<<<<
@@ -26060,10 +25872,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 '%s'", "_relabel_tables");
-    __PYX_ERR(0, 2289, __pyx_L1_error)
+    __PYX_ERR(0, 2363, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2292
+  /* "pywrapfst.pyx":2366
  *                          unknown_isymbol, attach_new_isymbols,
  *                          old_osymbols, new_osymbols,
  *                          unknown_osymbol, attach_new_osymbols)             # <<<<<<<<<<<<<<
@@ -26079,9 +25891,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, 2289, __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, 2363, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2293
+  /* "pywrapfst.pyx":2367
  *                          old_osymbols, new_osymbols,
  *                          unknown_osymbol, attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -26093,7 +25905,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2245
+  /* "pywrapfst.pyx":2319
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26111,7 +25923,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_tables(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2295
+/* "pywrapfst.pyx":2369
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26126,7 +25938,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2296
+  /* "pywrapfst.pyx":2370
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26135,28 +25947,28 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2296, __pyx_L1_error)
+    __PYX_ERR(0, 2370, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ReserveArcs(__pyx_v_state, __pyx_v_n) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2297
+    /* "pywrapfst.pyx":2371
  *   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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2297, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2297, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2371, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2297, __pyx_L1_error)
+    __PYX_ERR(0, 2371, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2296
+    /* "pywrapfst.pyx":2370
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -26165,7 +25977,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2298
+  /* "pywrapfst.pyx":2372
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26174,11 +25986,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2298, __pyx_L1_error)
+    __PYX_ERR(0, 2372, __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, 2298, __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, 2372, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2295
+  /* "pywrapfst.pyx":2369
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -26196,7 +26008,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2300
+/* "pywrapfst.pyx":2374
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26233,11 +26045,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43reserve_arcs(PyObject *__py
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2300, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2374, __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, 2300, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2374, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -26245,12 +26057,12 @@ 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, 2300, __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, 2300, __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, 2374, __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, 2374, __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, 2300, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2374, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26268,7 +26080,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2318
+  /* "pywrapfst.pyx":2392
  *     See also: `reserve_states`.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -26277,11 +26089,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 '%s'", "_reserve_arcs");
-    __PYX_ERR(0, 2318, __pyx_L1_error)
+    __PYX_ERR(0, 2392, __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, 2318, __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, 2392, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2319
+  /* "pywrapfst.pyx":2393
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26293,7 +26105,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2300
+  /* "pywrapfst.pyx":2374
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -26311,7 +26123,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42reserve_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2321
+/* "pywrapfst.pyx":2395
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26323,7 +26135,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2322
+  /* "pywrapfst.pyx":2396
  * 
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
@@ -26332,11 +26144,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2322, __pyx_L1_error)
+    __PYX_ERR(0, 2396, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2323
+  /* "pywrapfst.pyx":2397
  *   cdef void _reserve_states(self, int64 n) except *:
  *     self._mfst.get().ReserveStates(n)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26345,11 +26157,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2323, __pyx_L1_error)
+    __PYX_ERR(0, 2397, __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, 2323, __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, 2397, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2321
+  /* "pywrapfst.pyx":2395
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
@@ -26365,7 +26177,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2325
+/* "pywrapfst.pyx":2399
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26382,7 +26194,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_states(PyObject *__
   __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, 2325, __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, 2399, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -26402,7 +26214,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2339
+  /* "pywrapfst.pyx":2413
  *     See also: `reserve_arcs`.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
@@ -26411,11 +26223,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 '%s'", "_reserve_states");
-    __PYX_ERR(0, 2339, __pyx_L1_error)
+    __PYX_ERR(0, 2413, __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, 2339, __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, 2413, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2340
+  /* "pywrapfst.pyx":2414
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -26427,7 +26239,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2325
+  /* "pywrapfst.pyx":2399
  *     self._check_mutating_imethod()
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -26445,7 +26257,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_states(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2342
+/* "pywrapfst.pyx":2416
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -26472,7 +26284,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2344
+  /* "pywrapfst.pyx":2418
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -26483,11 +26295,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, 2344, __pyx_L1_error)
+    __PYX_ERR(0, 2418, __pyx_L1_error)
   }
   __pyx_v__potentials.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2345
+  /* "pywrapfst.pyx":2419
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()             # <<<<<<<<<<<<<<
@@ -26496,11 +26308,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 '%s'", "weight_type");
-    __PYX_ERR(0, 2345, __pyx_L1_error)
+    __PYX_ERR(0, 2419, __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":2346
+  /* "pywrapfst.pyx":2420
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -26511,26 +26323,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, 2346, __pyx_L1_error)
+    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2420, __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, 2346, __pyx_L1_error)
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2420, __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, 2346, __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, 2420, __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, 2346, __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, 2420, __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, 2346, __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, 2420, __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, 2346, __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, 2420, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         #endif
       }
@@ -26540,7 +26352,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2346, __pyx_L1_error)
+          else __PYX_ERR(0, 2420, __pyx_L1_error)
         }
         break;
       }
@@ -26549,7 +26361,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":2347
+    /* "pywrapfst.pyx":2421
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26558,19 +26370,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 '%s'", "weight_type");
-      __PYX_ERR(0, 2347, __pyx_L1_error)
+      __PYX_ERR(0, 2421, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2348
+    /* "pywrapfst.pyx":2422
  *     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, 2347, __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, 2421, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2347
+    /* "pywrapfst.pyx":2421
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26581,10 +26393,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, 2347, __pyx_L1_error)
+      __PYX_ERR(0, 2421, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2346
+    /* "pywrapfst.pyx":2420
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -26594,7 +26406,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2349
+  /* "pywrapfst.pyx":2423
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),             # <<<<<<<<<<<<<<
@@ -26603,10 +26415,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2349, __pyx_L1_error)
+    __PYX_ERR(0, 2423, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2350
+  /* "pywrapfst.pyx":2424
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
@@ -26615,7 +26427,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":2351
+  /* "pywrapfst.pyx":2425
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26624,11 +26436,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2351, __pyx_L1_error)
+    __PYX_ERR(0, 2425, __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)
+  ((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, 2425, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2342
+  /* "pywrapfst.pyx":2416
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -26647,7 +26459,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2353
+/* "pywrapfst.pyx":2427
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26688,7 +26500,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, 2353, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2427, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26700,14 +26512,14 @@ 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, 2353, __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, 2427, __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, 2353, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2427, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26726,7 +26538,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight __pyx_t_1;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2375
+  /* "pywrapfst.pyx":2449
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -26735,13 +26547,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 '%s'", "_reweight");
-    __PYX_ERR(0, 2375, __pyx_L1_error)
+    __PYX_ERR(0, 2449, __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, 2375, __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, 2449, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2376
+  /* "pywrapfst.pyx":2450
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -26753,7 +26565,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2353
+  /* "pywrapfst.pyx":2427
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26771,7 +26583,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reweight(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2378
+/* "pywrapfst.pyx":2452
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -26781,7 +26593,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) {
 
-  /* "pywrapfst.pyx":2379
+  /* "pywrapfst.pyx":2453
  * 
  *   cdef void _rmepsilon(self,
  *                        bool connect=True,             # <<<<<<<<<<<<<<
@@ -26789,10 +26601,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  *                        int64 nstate=fst.kNoStateId,
  */
   bool __pyx_v_connect = ((bool)1);
-  float __pyx_v_delta = __pyx_k__22;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__23;
+  float __pyx_v_delta = __pyx_k__26;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__27;
 
-  /* "pywrapfst.pyx":2382
+  /* "pywrapfst.pyx":2456
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None) except *:             # <<<<<<<<<<<<<<
@@ -26819,7 +26631,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2384
+  /* "pywrapfst.pyx":2458
  *                        weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -26828,20 +26640,20 @@ 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 '%s'", "weight_type");
-    __PYX_ERR(0, 2384, __pyx_L1_error)
+    __PYX_ERR(0, 2458, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2385
+  /* "pywrapfst.pyx":2459
  *     # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)             # <<<<<<<<<<<<<<
  *     fst.RmEpsilon(self._mfst.get(), connect, 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, 2384, __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, 2458, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2386
+  /* "pywrapfst.pyx":2460
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  *     fst.RmEpsilon(self._mfst.get(), connect, wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -26850,11 +26662,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2386, __pyx_L1_error)
+    __PYX_ERR(0, 2460, __pyx_L1_error)
   }
   fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), __pyx_v_connect, __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2387
+  /* "pywrapfst.pyx":2461
  *                                                        weight)
  *     fst.RmEpsilon(self._mfst.get(), connect, wc, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26863,11 +26675,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2387, __pyx_L1_error)
+    __PYX_ERR(0, 2461, __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, 2387, __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, 2461, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2378
+  /* "pywrapfst.pyx":2452
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -26883,7 +26695,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2389
+/* "pywrapfst.pyx":2463
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -26906,7 +26718,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_connect,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[4] = {0,0,0,0};
 
-    /* "pywrapfst.pyx":2393
+    /* "pywrapfst.pyx":2467
  *                 float delta=fst.kDelta,
  *                 int64 nstate=fst.kNoStateId,
  *                 weight=None):             # <<<<<<<<<<<<<<
@@ -26949,7 +26761,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, 2389, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2463, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26962,10 +26774,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
       }
     }
     if (values[0]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2390, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2464, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2390
+      /* "pywrapfst.pyx":2464
  * 
  *   def rmepsilon(self,
  *                 bool connect=True,             # <<<<<<<<<<<<<<
@@ -26975,20 +26787,20 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
       __pyx_v_connect = ((bool)1);
     }
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2391, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2465, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__24;
+      __pyx_v_delta = __pyx_k__28;
     }
     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, 2392, __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, 2466, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__25;
+      __pyx_v_nstate = __pyx_k__29;
     }
     __pyx_v_weight = values[3];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2389, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2463, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26996,7 +26808,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon(PyObject *__pyx_v
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_connect, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":2389
+  /* "pywrapfst.pyx":2463
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27015,7 +26827,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon __pyx_t_1;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2415
+  /* "pywrapfst.pyx":2489
  *         reverse (and which may be more efficient).
  *     """
  *     self._rmepsilon(connect, delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -27024,16 +26836,16 @@ 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 '%s'", "_rmepsilon");
-    __PYX_ERR(0, 2415, __pyx_L1_error)
+    __PYX_ERR(0, 2489, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 4;
   __pyx_t_1.connect = __pyx_v_connect;
   __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)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2415, __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, 2489, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2416
+  /* "pywrapfst.pyx":2490
  *     """
  *     self._rmepsilon(connect, delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -27045,7 +26857,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2389
+  /* "pywrapfst.pyx":2463
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -27063,7 +26875,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48rmepsilon(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2418
+/* "pywrapfst.pyx":2492
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27086,7 +26898,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2419
+  /* "pywrapfst.pyx":2493
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27095,28 +26907,28 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2419, __pyx_L1_error)
+    __PYX_ERR(0, 2493, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2420
+    /* "pywrapfst.pyx":2494
  *   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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2420, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2494, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2420, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2494, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2420, __pyx_L1_error)
+    __PYX_ERR(0, 2494, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2419
+    /* "pywrapfst.pyx":2493
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -27125,7 +26937,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2421
+  /* "pywrapfst.pyx":2495
  *     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(),             # <<<<<<<<<<<<<<
@@ -27134,20 +26946,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 '%s'", "weight_type");
-    __PYX_ERR(0, 2421, __pyx_L1_error)
+    __PYX_ERR(0, 2495, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2422
+  /* "pywrapfst.pyx":2496
  *       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_4 = __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, 2421, __pyx_L1_error)
+  __pyx_t_4 = __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, 2495, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_4;
 
-  /* "pywrapfst.pyx":2423
+  /* "pywrapfst.pyx":2497
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27156,28 +26968,28 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2423, __pyx_L1_error)
+    __PYX_ERR(0, 2497, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v_wc) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2424
+    /* "pywrapfst.pyx":2498
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2424, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2498, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2424, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2498, __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, 2424, __pyx_L1_error)
+    __PYX_ERR(0, 2498, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2423
+    /* "pywrapfst.pyx":2497
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -27186,7 +26998,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2425
+  /* "pywrapfst.pyx":2499
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27195,11 +27007,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2425, __pyx_L1_error)
+    __PYX_ERR(0, 2499, __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, 2425, __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, 2499, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2418
+  /* "pywrapfst.pyx":2492
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -27217,7 +27029,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2427
+/* "pywrapfst.pyx":2501
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27227,7 +27039,7 @@ 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 a state to be final with a fixed cost.\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    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n\n    See also: `set_start`.\n    ";
+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    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) {
   __pyx_t_10basictypes_int64 __pyx_v_state;
   PyObject *__pyx_v_weight = 0;
@@ -27259,7 +27071,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, 2427, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2501, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27269,12 +27081,12 @@ 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, 2427, __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, 2501, __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, 2427, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2501, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27293,7 +27105,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_
   struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final __pyx_t_1;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2444
+  /* "pywrapfst.pyx":2518
  *     See also: `set_start`.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
@@ -27302,25 +27114,25 @@ 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 '%s'", "_set_final");
-    __PYX_ERR(0, 2444, __pyx_L1_error)
+    __PYX_ERR(0, 2518, __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, 2444, __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, 2518, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2445
+  /* "pywrapfst.pyx":2519
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_properties(self, uint64 props, uint64 mask) except *:
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2427
+  /* "pywrapfst.pyx":2501
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -27338,155 +27150,176 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50set_final(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2447
+/* "pywrapfst.pyx":2521
  *     return self
  * 
- *   cdef void _set_properties(self, uint64 props, uint64 mask) except *:             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetProperties(props, mask)
- * 
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mfst.get().SetInputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_set_properties", 0);
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2448
+  /* "pywrapfst.pyx":2522
  * 
- *   cdef void _set_properties(self, uint64 props, uint64 mask) except *:
- *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mfst.get().SetInputSymbols(NULL)
+ *       return
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "pywrapfst.pyx":2523
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:
+ *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
+ *       return
+ *     self._mfst.get().SetInputSymbols(syms._table)
+ */
+    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
+      __PYX_ERR(0, 2523, __pyx_L1_error)
+    }
+    __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
+
+    /* "pywrapfst.pyx":2524
+ *     if syms is None:
+ *       self._mfst.get().SetInputSymbols(NULL)
+ *       return             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetInputSymbols(syms._table)
+ *     self._check_mutating_imethod()
+ */
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":2522
+ * 
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mfst.get().SetInputSymbols(NULL)
+ *       return
+ */
+  }
+
+  /* "pywrapfst.pyx":2525
+ *       self._mfst.get().SetInputSymbols(NULL)
+ *       return
+ *     self._mfst.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
+ *     self._check_mutating_imethod()
  * 
- *   def set_properties(self, uint64 props, uint64 mask):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2448, __pyx_L1_error)
+    __PYX_ERR(0, 2525, __pyx_L1_error)
   }
-  __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
+  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
+    __PYX_ERR(0, 2525, __pyx_L1_error)
+  }
+  __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2447
- *     return self
+  /* "pywrapfst.pyx":2526
+ *       return
+ *     self._mfst.get().SetInputSymbols(syms._table)
+ *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_properties(self, uint64 props, uint64 mask) except *:             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetProperties(props, mask)
+ *   def set_input_symbols(self, _SymbolTable syms):
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
+    __PYX_ERR(0, 2526, __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, 2526, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":2521
+ *     return self
  * 
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mfst.get().SetInputSymbols(NULL)
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst._set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2450
- *     self._mfst.get().SetProperties(props, mask)
+/* "pywrapfst.pyx":2528
+ *     self._check_mutating_imethod()
  * 
- *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
- *     set_properties(self, props, mask)
+ *     set_input_symbols(self, syms)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_52set_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\n        setting the FST's properties.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_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;
+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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("set_properties (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_props,&__pyx_n_s_mask,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_props)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2450, __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, 2450, __pyx_L3_error)
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      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, 2450, __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, 2450, __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, 2450, __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_52set_properties(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_props, __pyx_v_mask);
+  __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, 2528, __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));
 
   /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_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_52set_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_properties", 0);
+  __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2464
- *       self.
+  /* "pywrapfst.pyx":2544
+ *     See also: `set_output_symbols`.
  *     """
- *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
+ *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_properties");
-    __PYX_ERR(0, 2464, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_input_symbols");
+    __PYX_ERR(0, 2544, __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); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2464, __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, 2544, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2465
+  /* "pywrapfst.pyx":2545
  *     """
- *     self._set_properties(props, mask)
+ *     self._set_input_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_start(self, int64 state) except *:
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2450
- *     self._mfst.get().SetProperties(props, mask)
+  /* "pywrapfst.pyx":2528
+ *     self._check_mutating_imethod()
  * 
- *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
- *     set_properties(self, props, mask)
+ *     set_input_symbols(self, syms)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27494,164 +27327,176 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_properties(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2467
+/* "pywrapfst.pyx":2547
  *     return self
  * 
- *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
- *     if not self._mfst.get().SetStart(state):
- *       raise FstIndexError("State index out of range")
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mfst.get().SetOutputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  __Pyx_RefNannySetupContext("_set_start", 0);
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2468
+  /* "pywrapfst.pyx":2548
  * 
- *   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()
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mfst.get().SetOutputSymbols(NULL)
+ *       return
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2468, __pyx_L1_error)
-  }
-  __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
-  if (__pyx_t_1) {
+  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2469
- *   cdef void _set_start(self, int64 state) except *:
- *     if not self._mfst.get().SetStart(state):
- *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":2549
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:
+ *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
+ *       return
+ *     self._mfst.get().SetOutputSymbols(syms._table)
+ */
+    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
+      __PYX_ERR(0, 2549, __pyx_L1_error)
+    }
+    __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
+
+    /* "pywrapfst.pyx":2550
+ *     if syms is None:
+ *       self._mfst.get().SetOutputSymbols(NULL)
+ *       return             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetOutputSymbols(syms._table)
  *     self._check_mutating_imethod()
- * 
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2469, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2469, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2469, __pyx_L1_error)
+    goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2468
+    /* "pywrapfst.pyx":2548
  * 
- *   cdef void _set_start(self, int64 state) except *:
- *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
- *       raise FstIndexError("State index out of range")
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mfst.get().SetOutputSymbols(NULL)
+ *       return
+ */
+  }
+
+  /* "pywrapfst.pyx":2551
+ *       self._mfst.get().SetOutputSymbols(NULL)
+ *       return
+ *     self._mfst.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
+ * 
  */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
+    __PYX_ERR(0, 2551, __pyx_L1_error)
+  }
+  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
+    __PYX_ERR(0, 2551, __pyx_L1_error)
   }
+  __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2470
- *     if not self._mfst.get().SetStart(state):
- *       raise FstIndexError("State index out of range")
+  /* "pywrapfst.pyx":2552
+ *       return
+ *     self._mfst.get().SetOutputSymbols(syms._table)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def set_start(self, int64 state):
+ *   def set_output_symbols(self, _SymbolTable syms):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2470, __pyx_L1_error)
+    __PYX_ERR(0, 2552, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2470, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2552, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2467
+  /* "pywrapfst.pyx":2547
  *     return self
  * 
- *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
- *     if not self._mfst.get().SetStart(state):
- *       raise FstIndexError("State index out of range")
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mfst.get().SetOutputSymbols(NULL)
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst._set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2472
+/* "pywrapfst.pyx":2554
  *     self._check_mutating_imethod()
  * 
- *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
- *     set_start(self, state)
+ *     set_output_symbols(self, syms)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_54set_start[] = "\n    set_start(self, state)\n\n    Sets the initial 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_55set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+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) {
   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, 2472, __pyx_L3_error)
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_54set_start(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __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, 2554, __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));
 
   /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("set_start", 0);
+  __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2489
- *     See also: `set_final`.
+  /* "pywrapfst.pyx":2570
+ *     See also: `set_input_symbols`.
  *     """
- *     self._set_start(state)             # <<<<<<<<<<<<<<
+ *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_start");
-    __PYX_ERR(0, 2489, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_output_symbols");
+    __PYX_ERR(0, 2570, __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, 2489, __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, 2570, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2490
+  /* "pywrapfst.pyx":2571
  *     """
- *     self._set_start(state)
+ *     self._set_output_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_properties(self, uint64 props, uint64 mask):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2472
+  /* "pywrapfst.pyx":2554
  *     self._check_mutating_imethod()
  * 
- *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
- *     set_start(self, state)
+ *     set_output_symbols(self, syms)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27659,176 +27504,155 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_start(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2492
+/* "pywrapfst.pyx":2573
  *     return self
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
- *       self._mfst.get().SetInputSymbols(NULL)
- */
-
-static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  __Pyx_RefNannySetupContext("_set_input_symbols", 0);
-
-  /* "pywrapfst.pyx":2493
+ *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetProperties(props, mask)
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
- *       self._mfst.get().SetInputSymbols(NULL)
- *       return
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
-  __pyx_t_2 = (__pyx_t_1 != 0);
-  if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2494
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
- *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
- *       return
- *     self._mfst.get().SetInputSymbols(syms._table)
- */
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-      __PYX_ERR(0, 2494, __pyx_L1_error)
-    }
-    __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
-
-    /* "pywrapfst.pyx":2495
- *     if syms is None:
- *       self._mfst.get().SetInputSymbols(NULL)
- *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetInputSymbols(syms._table)
- *     self._check_mutating_imethod()
- */
-    goto __pyx_L0;
+static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_set_properties", 0);
 
-    /* "pywrapfst.pyx":2493
+  /* "pywrapfst.pyx":2574
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
- *       self._mfst.get().SetInputSymbols(NULL)
- *       return
- */
-  }
-
-  /* "pywrapfst.pyx":2496
- *       self._mfst.get().SetInputSymbols(NULL)
- *       return
- *     self._mfst.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
+ *   cdef void _set_properties(self, uint64 props, uint64 mask):
+ *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
  * 
+ *   def set_properties(self, uint64 props, uint64 mask):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2496, __pyx_L1_error)
-  }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 2496, __pyx_L1_error)
-  }
-  __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_v_syms->_table);
-
-  /* "pywrapfst.pyx":2497
- *       return
- *     self._mfst.get().SetInputSymbols(syms._table)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def set_input_symbols(self, _SymbolTable syms):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2497, __pyx_L1_error)
+    __PYX_ERR(0, 2574, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2497, __pyx_L1_error)
+  __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2492
+  /* "pywrapfst.pyx":2573
  *     return self
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
- *       self._mfst.get().SetInputSymbols(NULL)
+ *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetProperties(props, mask)
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst._MutableFst._set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2499
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2576
+ *     self._mfst.get().SetProperties(props, mask)
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_properties(self, props, mask)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_56set_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_57set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+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) {
+  __pyx_t_10basictypes_uint64 __pyx_v_props;
+  __pyx_t_10basictypes_uint64 __pyx_v_mask;
   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, 2499, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_56set_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  __Pyx_RefNannySetupContext("set_properties (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_props,&__pyx_n_s_mask,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_props)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2576, __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, 2576, __pyx_L3_error)
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      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, 2576, __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, 2576, __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, 2576, __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);
 
   /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_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_56set_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_input_symbols", 0);
+  __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2515
- *     See also: `set_output_symbols`.
+  /* "pywrapfst.pyx":2590
+ *       self.
  *     """
- *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_input_symbols");
-    __PYX_ERR(0, 2515, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_properties");
+    __PYX_ERR(0, 2590, __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, 2515, __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":2516
+  /* "pywrapfst.pyx":2591
  *     """
- *     self._set_input_symbols(syms)
+ *     self._set_properties(props, mask)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_start(self, int64 state) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2499
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2576
+ *     self._mfst.get().SetProperties(props, mask)
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_properties(self, props, mask)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27836,156 +27660,144 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_input_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2518
+/* "pywrapfst.pyx":2593
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
- *       self._mfst.get().SetOutputSymbols(NULL)
+ *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
+ *     if not self._mfst.get().SetStart(state):
+ *       raise FstIndexError("State index out of range")
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
-  int __pyx_t_2;
-  __Pyx_RefNannySetupContext("_set_output_symbols", 0);
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2519
+  /* "pywrapfst.pyx":2594
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
- *       self._mfst.get().SetOutputSymbols(NULL)
- *       return
- */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
-  __pyx_t_2 = (__pyx_t_1 != 0);
-  if (__pyx_t_2) {
-
-    /* "pywrapfst.pyx":2520
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
- *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
- *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)
- */
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-      __PYX_ERR(0, 2520, __pyx_L1_error)
-    }
-    __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
-
-    /* "pywrapfst.pyx":2521
- *     if syms is None:
- *       self._mfst.get().SetOutputSymbols(NULL)
- *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetOutputSymbols(syms._table)
+ *   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()
  */
-    goto __pyx_L0;
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
+    __PYX_ERR(0, 2594, __pyx_L1_error)
+  }
+  __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
+  if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2519
+    /* "pywrapfst.pyx":2595
+ *   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()
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
- *       self._mfst.get().SetOutputSymbols(NULL)
- *       return
  */
-  }
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2595, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2595, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __PYX_ERR(0, 2595, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2522
- *       self._mfst.get().SetOutputSymbols(NULL)
- *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
+    /* "pywrapfst.pyx":2594
  * 
+ *   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()
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2522, __pyx_L1_error)
-  }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_table");
-    __PYX_ERR(0, 2522, __pyx_L1_error)
   }
-  __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_v_syms->_table);
 
-  /* "pywrapfst.pyx":2523
- *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)
+  /* "pywrapfst.pyx":2596
+ *     if not self._mfst.get().SetStart(state):
+ *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def set_output_symbols(self, _SymbolTable syms):
+ *   def set_start(self, int64 state):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2523, __pyx_L1_error)
+    __PYX_ERR(0, 2596, __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, 2523, __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, 2596, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2518
+  /* "pywrapfst.pyx":2593
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
- *       self._mfst.get().SetOutputSymbols(NULL)
+ *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
+ *     if not self._mfst.get().SetStart(state):
+ *       raise FstIndexError("State index out of range")
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pywrapfst._MutableFst._set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2525
+/* "pywrapfst.pyx":2598
  *     self._check_mutating_imethod()
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_start(self, state)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_58set_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_59set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+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) {
+  __pyx_t_10basictypes_int64 __pyx_v_state;
   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, 2525, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_58set_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  __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, 2598, __pyx_L3_error)
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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));
 
   /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_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_58set_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_output_symbols", 0);
+  __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2541
- *     See also: `set_input_symbols`.
+  /* "pywrapfst.pyx":2615
+ *     See also: `set_final`.
  *     """
- *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_start(state)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_output_symbols");
-    __PYX_ERR(0, 2541, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_set_start");
+    __PYX_ERR(0, 2615, __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, 2541, __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, 2615, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2542
+  /* "pywrapfst.pyx":2616
  *     """
- *     self._set_output_symbols(syms)
+ *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _topsort(self) except *:
@@ -27995,17 +27807,17 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_output_symbols(struct _
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2525
+  /* "pywrapfst.pyx":2598
  *     self._check_mutating_imethod()
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_start(self, state)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -28013,7 +27825,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_output_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2544
+/* "pywrapfst.pyx":2618
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28028,7 +27840,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2546
+  /* "pywrapfst.pyx":2620
  *   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()):             # <<<<<<<<<<<<<<
@@ -28037,29 +27849,29 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 2546, __pyx_L1_error)
+    __PYX_ERR(0, 2620, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2547
+    /* "pywrapfst.pyx":2621
  *     # 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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2547, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2621, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2547, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2621, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2547, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2621, __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;
 
-    /* "pywrapfst.pyx":2546
+    /* "pywrapfst.pyx":2620
  *   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()):             # <<<<<<<<<<<<<<
@@ -28068,7 +27880,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":2548
+  /* "pywrapfst.pyx":2622
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST.")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28077,11 +27889,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2548, __pyx_L1_error)
+    __PYX_ERR(0, 2622, __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, 2548, __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, 2622, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2544
+  /* "pywrapfst.pyx":2618
  *     return self
  * 
  *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
@@ -28099,7 +27911,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2550
+/* "pywrapfst.pyx":2624
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28126,7 +27938,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2565
+  /* "pywrapfst.pyx":2639
  *     See also: `arcsort`.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -28135,11 +27947,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 '%s'", "_topsort");
-    __PYX_ERR(0, 2565, __pyx_L1_error)
+    __PYX_ERR(0, 2639, __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, 2565, __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, 2639, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2566
+  /* "pywrapfst.pyx":2640
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
@@ -28151,7 +27963,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2550
+  /* "pywrapfst.pyx":2624
  *     self._check_mutating_imethod()
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -28169,7 +27981,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60topsort(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2568
+/* "pywrapfst.pyx":2642
  *     return self
  * 
  *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -28181,7 +27993,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_union", 0);
 
-  /* "pywrapfst.pyx":2569
+  /* "pywrapfst.pyx":2643
  * 
  *   cdef void _union(self, _Fst ifst) except *:
  *     fst.Union(self._mfst.get(), deref(ifst._fst))             # <<<<<<<<<<<<<<
@@ -28190,15 +28002,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 '%s'", "_mfst");
-    __PYX_ERR(0, 2569, __pyx_L1_error)
+    __PYX_ERR(0, 2643, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 2569, __pyx_L1_error)
+    __PYX_ERR(0, 2643, __pyx_L1_error)
   }
   fst::script::Union(__pyx_v_self->_mfst.get(), (*__pyx_v_ifst->_fst));
 
-  /* "pywrapfst.pyx":2570
+  /* "pywrapfst.pyx":2644
  *   cdef void _union(self, _Fst ifst) except *:
  *     fst.Union(self._mfst.get(), deref(ifst._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28207,11 +28019,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 '%s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2570, __pyx_L1_error)
+    __PYX_ERR(0, 2644, __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, 2570, __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, 2644, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2568
+  /* "pywrapfst.pyx":2642
  *     return self
  * 
  *   cdef void _union(self, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -28227,7 +28039,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__union(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2572
+/* "pywrapfst.pyx":2646
  *     self._check_mutating_imethod()
  * 
  *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -28242,7 +28054,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63union(PyObject *__pyx_v_sel
   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, 2572, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 2646, __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));
 
   /* function exit code */
@@ -28259,7 +28071,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2588
+  /* "pywrapfst.pyx":2662
  *       self.
  *     """
  *     self._union(ifst)             # <<<<<<<<<<<<<<
@@ -28268,11 +28080,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 '%s'", "_union");
-    __PYX_ERR(0, 2588, __pyx_L1_error)
+    __PYX_ERR(0, 2662, __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, 2588, __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, 2662, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2589
+  /* "pywrapfst.pyx":2663
  *     """
  *     self._union(ifst)
  *     return self             # <<<<<<<<<<<<<<
@@ -28284,7 +28096,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2572
+  /* "pywrapfst.pyx":2646
  *     self._check_mutating_imethod()
  * 
  *   def union(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -28302,7 +28114,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62union(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2614
+/* "pywrapfst.pyx":2688
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28319,7 +28131,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2615
+  /* "pywrapfst.pyx":2689
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):             # <<<<<<<<<<<<<<
@@ -28329,23 +28141,23 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   __pyx_t_1 = (__pyx_v_tfst->Properties(fst::kError, 1) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2616
+    /* "pywrapfst.pyx":2690
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(<FstClass_ptr> tfst)
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2616, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2690, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2616, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2690, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2616, __pyx_L1_error)
+    __PYX_ERR(0, 2690, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2615
+    /* "pywrapfst.pyx":2689
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):             # <<<<<<<<<<<<<<
@@ -28354,20 +28166,20 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
  */
   }
 
-  /* "pywrapfst.pyx":2617
+  /* "pywrapfst.pyx":2691
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")
  *   cdef _Fst ofst = _Fst.__new__(_Fst)             # <<<<<<<<<<<<<<
  *   ofst._fst.reset(<FstClass_ptr> tfst)
  *   return ofst
  */
-  __pyx_t_3 = __pyx_tp_new_9pywrapfst__Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst__Fst), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2617, __pyx_L1_error)
+  __pyx_t_3 = __pyx_tp_new_9pywrapfst__Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst__Fst), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2691, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst)))) __PYX_ERR(0, 2617, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst)))) __PYX_ERR(0, 2691, __pyx_L1_error)
   __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2618
+  /* "pywrapfst.pyx":2692
  *     raise FstOpError("Operation failed")
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(<FstClass_ptr> tfst)             # <<<<<<<<<<<<<<
@@ -28376,11 +28188,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 '%s'", "_fst");
-    __PYX_ERR(0, 2618, __pyx_L1_error)
+    __PYX_ERR(0, 2692, __pyx_L1_error)
   }
   __pyx_v_ofst->_fst.reset(((__pyx_t_9pywrapfst_FstClass_ptr)__pyx_v_tfst));
 
-  /* "pywrapfst.pyx":2619
+  /* "pywrapfst.pyx":2693
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(<FstClass_ptr> tfst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -28392,7 +28204,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":2614
+  /* "pywrapfst.pyx":2688
  * 
  * 
  * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28413,7 +28225,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2622
+/* "pywrapfst.pyx":2696
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28430,7 +28242,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2623
+  /* "pywrapfst.pyx":2697
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):             # <<<<<<<<<<<<<<
@@ -28440,23 +28252,23 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_t_1 = (__pyx_v_tfst->Properties(fst::kError, 1) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2624
+    /* "pywrapfst.pyx":2698
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(<MutableFstClass_ptr> tfst)
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2624, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2698, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2624, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2698, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2624, __pyx_L1_error)
+    __PYX_ERR(0, 2698, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2623
+    /* "pywrapfst.pyx":2697
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):             # <<<<<<<<<<<<<<
@@ -28465,20 +28277,20 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   }
 
-  /* "pywrapfst.pyx":2625
+  /* "pywrapfst.pyx":2699
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)             # <<<<<<<<<<<<<<
  *   ofst._fst.reset(<MutableFstClass_ptr> tfst)
  *   # Makes a copy of it as the derived type! Cool.
  */
-  __pyx_t_3 = __pyx_tp_new_9pywrapfst__MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFst), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2625, __pyx_L1_error)
+  __pyx_t_3 = __pyx_tp_new_9pywrapfst__MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFst), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2699, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__MutableFst)))) __PYX_ERR(0, 2625, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__MutableFst)))) __PYX_ERR(0, 2699, __pyx_L1_error)
   __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":2626
+  /* "pywrapfst.pyx":2700
  *     raise FstOpError("Operation failed")
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(<MutableFstClass_ptr> tfst)             # <<<<<<<<<<<<<<
@@ -28487,11 +28299,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 '%s'", "_fst");
-    __PYX_ERR(0, 2626, __pyx_L1_error)
+    __PYX_ERR(0, 2700, __pyx_L1_error)
   }
   __pyx_v_ofst->__pyx_base._fst.reset(((__pyx_t_9pywrapfst_MutableFstClass_ptr)__pyx_v_tfst));
 
-  /* "pywrapfst.pyx":2628
+  /* "pywrapfst.pyx":2702
  *   ofst._fst.reset(<MutableFstClass_ptr> tfst)
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)             # <<<<<<<<<<<<<<
@@ -28500,15 +28312,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 '%s'", "_fst");
-    __PYX_ERR(0, 2628, __pyx_L1_error)
+    __PYX_ERR(0, 2702, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 2628, __pyx_L1_error)
+    __PYX_ERR(0, 2702, __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":2629
+  /* "pywrapfst.pyx":2703
  *   # Makes a copy of it as the derived type! Cool.
  *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
  *   return ofst             # <<<<<<<<<<<<<<
@@ -28520,7 +28332,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2622
+  /* "pywrapfst.pyx":2696
  * 
  * 
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28541,7 +28353,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2632
+/* "pywrapfst.pyx":2706
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28556,7 +28368,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":2633
+  /* "pywrapfst.pyx":2707
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True):             # <<<<<<<<<<<<<<
@@ -28566,7 +28378,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) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2634
+    /* "pywrapfst.pyx":2708
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True):
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
@@ -28574,13 +28386,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, 2634, __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, 2708, __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":2633
+    /* "pywrapfst.pyx":2707
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True):             # <<<<<<<<<<<<<<
@@ -28589,7 +28401,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  */
   }
 
-  /* "pywrapfst.pyx":2636
+  /* "pywrapfst.pyx":2710
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -28598,14 +28410,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, 2636, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2710, __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":2632
+  /* "pywrapfst.pyx":2706
  * 
  * 
  * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -28624,7 +28436,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2639
+/* "pywrapfst.pyx":2713
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -28652,16 +28464,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     }
   }
 
-  /* "pywrapfst.pyx":2641
+  /* "pywrapfst.pyx":2715
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):
  *   cdef fst.VectorFstClass *tfst = new fst.VectorFstClass(
  *       <string> tostring(arc_type))             # <<<<<<<<<<<<<<
  *   if tfst == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2641, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2715, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2640
+  /* "pywrapfst.pyx":2714
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):
  *   cdef fst.VectorFstClass *tfst = new fst.VectorFstClass(             # <<<<<<<<<<<<<<
@@ -28670,7 +28482,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  */
   __pyx_v_tfst = new fst::script::VectorFstClass(((std::string)__pyx_t_1));
 
-  /* "pywrapfst.pyx":2642
+  /* "pywrapfst.pyx":2716
  *   cdef fst.VectorFstClass *tfst = new fst.VectorFstClass(
  *       <string> tostring(arc_type))
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -28680,16 +28492,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   __pyx_t_2 = ((__pyx_v_tfst == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2643
+    /* "pywrapfst.pyx":2717
  *       <string> tostring(arc_type))
  *   if tfst == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  *   return _init_MutableFst(tfst)
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2643, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2717, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2643, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2717, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -28702,13 +28514,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2643, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2717, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_arc_type};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -28716,19 +28528,19 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_arc_type};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_arc_type);
         __Pyx_GIVEREF(__pyx_v_arc_type);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_arc_type);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -28745,14 +28557,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2643, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2717, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -28761,20 +28573,20 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2643, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2717, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -28782,9 +28594,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
     __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, 2643, __pyx_L1_error)
+    __PYX_ERR(0, 2717, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2642
+    /* "pywrapfst.pyx":2716
  *   cdef fst.VectorFstClass *tfst = new fst.VectorFstClass(
  *       <string> tostring(arc_type))
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -28793,7 +28605,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
  */
   }
 
-  /* "pywrapfst.pyx":2644
+  /* "pywrapfst.pyx":2718
  *   if tfst == NULL:
  *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -28801,13 +28613,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)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2644, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2718, __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":2639
+  /* "pywrapfst.pyx":2713
  * 
  * 
  * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -28831,7 +28643,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2647
+/* "pywrapfst.pyx":2721
  * 
  * 
  * cdef _Fst _read_Fst(filename, fst_type=None):             # <<<<<<<<<<<<<<
@@ -28860,17 +28672,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
     }
   }
 
-  /* "pywrapfst.pyx":2648
+  /* "pywrapfst.pyx":2722
  * 
  * cdef _Fst _read_Fst(filename, fst_type=None):
  *   cdef fst.FstClass *tfst = fst.FstClass.Read(tostring(filename))             # <<<<<<<<<<<<<<
  *   if tfst == NULL:
  *     raise FstIOError("Read failed: {!r}".format(filename))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2648, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2722, __pyx_L1_error)
   __pyx_v_tfst = fst::script::FstClass::Read(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2649
+  /* "pywrapfst.pyx":2723
  * cdef _Fst _read_Fst(filename, fst_type=None):
  *   cdef fst.FstClass *tfst = fst.FstClass.Read(tostring(filename))
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -28880,16 +28692,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
   __pyx_t_2 = ((__pyx_v_tfst == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2650
+    /* "pywrapfst.pyx":2724
  *   cdef fst.FstClass *tfst = fst.FstClass.Read(tostring(filename))
  *   if tfst == NULL:
  *     raise FstIOError("Read failed: {!r}".format(filename))             # <<<<<<<<<<<<<<
  *   # Converts if requested.
  *   cdef string fst_type_string
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2650, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2724, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2650, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2724, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -28902,13 +28714,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2650, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_filename); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2724, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -28916,19 +28728,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_filename};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_filename);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -28945,14 +28757,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2650, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2724, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -28961,20 +28773,20 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2650, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2724, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -28982,9 +28794,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
     __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, 2650, __pyx_L1_error)
+    __PYX_ERR(0, 2724, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2649
+    /* "pywrapfst.pyx":2723
  * cdef _Fst _read_Fst(filename, fst_type=None):
  *   cdef fst.FstClass *tfst = fst.FstClass.Read(tostring(filename))
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -28993,27 +28805,27 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
  */
   }
 
-  /* "pywrapfst.pyx":2653
+  /* "pywrapfst.pyx":2727
  *   # Converts if requested.
  *   cdef string fst_type_string
  *   if fst_type:             # <<<<<<<<<<<<<<
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != tfst.FstType():
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_fst_type); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2653, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_fst_type); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2727, __pyx_L1_error)
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2654
+    /* "pywrapfst.pyx":2728
  *   cdef string fst_type_string
  *   if fst_type:
  *     fst_type_string = tostring(fst_type)             # <<<<<<<<<<<<<<
  *     if fst_type_string != tfst.FstType():
  *       tfst = fst.Convert(deref(tfst), fst_type_string)
  */
-    __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2654, __pyx_L1_error)
+    __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2728, __pyx_L1_error)
     __pyx_v_fst_type_string = __pyx_t_1;
 
-    /* "pywrapfst.pyx":2655
+    /* "pywrapfst.pyx":2729
  *   if fst_type:
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != tfst.FstType():             # <<<<<<<<<<<<<<
@@ -29023,7 +28835,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
     __pyx_t_2 = ((__pyx_v_fst_type_string != __pyx_v_tfst->FstType()) != 0);
     if (__pyx_t_2) {
 
-      /* "pywrapfst.pyx":2656
+      /* "pywrapfst.pyx":2730
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != tfst.FstType():
  *       tfst = fst.Convert(deref(tfst), fst_type_string)             # <<<<<<<<<<<<<<
@@ -29032,7 +28844,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
  */
       __pyx_v_tfst = fst::script::Convert((*__pyx_v_tfst), __pyx_v_fst_type_string);
 
-      /* "pywrapfst.pyx":2657
+      /* "pywrapfst.pyx":2731
  *     if fst_type_string != tfst.FstType():
  *       tfst = fst.Convert(deref(tfst), fst_type_string)
  *       if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -29042,16 +28854,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
       __pyx_t_2 = ((__pyx_v_tfst == NULL) != 0);
       if (__pyx_t_2) {
 
-        /* "pywrapfst.pyx":2658
+        /* "pywrapfst.pyx":2732
  *       tfst = fst.Convert(deref(tfst), fst_type_string)
  *       if tfst == NULL:
  *         raise FstOpError("Conversion to {!r} failed.".format(fst_type))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst)
  * 
  */
-        __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2658, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2732, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2658, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2732, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __pyx_t_6 = NULL;
         if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -29064,13 +28876,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
           }
         }
         if (!__pyx_t_6) {
-          __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fst_type); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2658, __pyx_L1_error)
+          __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fst_type); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2732, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
         } else {
           #if CYTHON_FAST_PYCALL
           if (PyFunction_Check(__pyx_t_5)) {
             PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_fst_type};
-            __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
             __Pyx_GOTREF(__pyx_t_8);
           } else
@@ -29078,19 +28890,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
           #if CYTHON_FAST_PYCCALL
           if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
             PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_fst_type};
-            __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
             __Pyx_GOTREF(__pyx_t_8);
           } else
           #endif
           {
-            __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_7);
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
             __Pyx_INCREF(__pyx_v_fst_type);
             __Pyx_GIVEREF(__pyx_v_fst_type);
             PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_fst_type);
-            __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_8);
             __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
           }
@@ -29107,14 +28919,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
           }
         }
         if (!__pyx_t_5) {
-          __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2658, __pyx_L1_error)
+          __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2732, __pyx_L1_error)
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
           __Pyx_GOTREF(__pyx_t_3);
         } else {
           #if CYTHON_FAST_PYCALL
           if (PyFunction_Check(__pyx_t_4)) {
             PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_8};
-            __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
@@ -29123,20 +28935,20 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
           #if CYTHON_FAST_PYCCALL
           if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
             PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_8};
-            __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
           } else
           #endif
           {
-            __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_7);
             __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
             __Pyx_GIVEREF(__pyx_t_8);
             PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_8);
             __pyx_t_8 = 0;
-            __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2658, __pyx_L1_error)
+            __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2732, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_3);
             __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
           }
@@ -29144,9 +28956,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
         __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, 2658, __pyx_L1_error)
+        __PYX_ERR(0, 2732, __pyx_L1_error)
 
-        /* "pywrapfst.pyx":2657
+        /* "pywrapfst.pyx":2731
  *     if fst_type_string != tfst.FstType():
  *       tfst = fst.Convert(deref(tfst), fst_type_string)
  *       if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -29155,7 +28967,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
  */
       }
 
-      /* "pywrapfst.pyx":2655
+      /* "pywrapfst.pyx":2729
  *   if fst_type:
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != tfst.FstType():             # <<<<<<<<<<<<<<
@@ -29164,7 +28976,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
  */
     }
 
-    /* "pywrapfst.pyx":2653
+    /* "pywrapfst.pyx":2727
  *   # Converts if requested.
  *   cdef string fst_type_string
  *   if fst_type:             # <<<<<<<<<<<<<<
@@ -29173,21 +28985,21 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
  */
   }
 
-  /* "pywrapfst.pyx":2659
+  /* "pywrapfst.pyx":2733
  *       if tfst == NULL:
  *         raise FstOpError("Conversion to {!r} failed.".format(fst_type))
  *   return _init_XFst(tfst)             # <<<<<<<<<<<<<<
  * 
- * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
+ * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2659, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2733, __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":2647
+  /* "pywrapfst.pyx":2721
  * 
  * 
  * cdef _Fst _read_Fst(filename, fst_type=None):             # <<<<<<<<<<<<<<
@@ -29211,8 +29023,8 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2661
- *   return _init_XFst(tfst)
+/* "pywrapfst.pyx":2736
+ * 
  * 
  * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
  *   ofst = fst.FstClass.ReadFromString(fst_string)
@@ -29241,17 +29053,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
     }
   }
 
-  /* "pywrapfst.pyx":2662
+  /* "pywrapfst.pyx":2737
  * 
  * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
  *   ofst = fst.FstClass.ReadFromString(fst_string)             # <<<<<<<<<<<<<<
  *   if fst_type is not None:
  *     fst_type_string = tostring(fst_type)
  */
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_fst_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2662, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_fst_string); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2737, __pyx_L1_error)
   __pyx_v_ofst = fst::script::FstClass::ReadFromString(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2663
+  /* "pywrapfst.pyx":2738
  * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
  *   ofst = fst.FstClass.ReadFromString(fst_string)
  *   if fst_type is not None:             # <<<<<<<<<<<<<<
@@ -29262,17 +29074,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
   __pyx_t_3 = (__pyx_t_2 != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":2664
+    /* "pywrapfst.pyx":2739
  *   ofst = fst.FstClass.ReadFromString(fst_string)
  *   if fst_type is not None:
  *     fst_type_string = tostring(fst_type)             # <<<<<<<<<<<<<<
  *     if fst_type_string != ofst.FstType():
  *       ofst = fst.Convert(deref(ofst), fst_type_string)
  */
-    __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2664, __pyx_L1_error)
+    __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2739, __pyx_L1_error)
     __pyx_v_fst_type_string = __pyx_t_1;
 
-    /* "pywrapfst.pyx":2665
+    /* "pywrapfst.pyx":2740
  *   if fst_type is not None:
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != ofst.FstType():             # <<<<<<<<<<<<<<
@@ -29282,7 +29094,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
     __pyx_t_3 = ((__pyx_v_fst_type_string != __pyx_v_ofst->FstType()) != 0);
     if (__pyx_t_3) {
 
-      /* "pywrapfst.pyx":2666
+      /* "pywrapfst.pyx":2741
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != ofst.FstType():
  *       ofst = fst.Convert(deref(ofst), fst_type_string)             # <<<<<<<<<<<<<<
@@ -29291,7 +29103,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
  */
       __pyx_v_ofst = fst::script::Convert((*__pyx_v_ofst), __pyx_v_fst_type_string);
 
-      /* "pywrapfst.pyx":2667
+      /* "pywrapfst.pyx":2742
  *     if fst_type_string != ofst.FstType():
  *       ofst = fst.Convert(deref(ofst), fst_type_string)
  *       if ofst == NULL:             # <<<<<<<<<<<<<<
@@ -29301,16 +29113,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
       __pyx_t_3 = ((__pyx_v_ofst == NULL) != 0);
       if (__pyx_t_3) {
 
-        /* "pywrapfst.pyx":2668
+        /* "pywrapfst.pyx":2743
  *       ofst = fst.Convert(deref(ofst), fst_type_string)
  *       if ofst == NULL:
  *         raise FstOpError("Conversion to {!r} failed.".format(fst_type))             # <<<<<<<<<<<<<<
  *   return _init_XFst(ofst)
  * 
  */
-        __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2668, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2743, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2668, __pyx_L1_error)
+        __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2743, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         __pyx_t_8 = NULL;
         if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -29323,13 +29135,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
           }
         }
         if (!__pyx_t_8) {
-          __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_fst_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2668, __pyx_L1_error)
+          __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_fst_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2743, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
         } else {
           #if CYTHON_FAST_PYCALL
           if (PyFunction_Check(__pyx_t_7)) {
             PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_fst_type};
-            __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
             __Pyx_GOTREF(__pyx_t_6);
           } else
@@ -29337,19 +29149,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
           #if CYTHON_FAST_PYCCALL
           if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
             PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_fst_type};
-            __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
             __Pyx_GOTREF(__pyx_t_6);
           } else
           #endif
           {
-            __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
             __Pyx_INCREF(__pyx_v_fst_type);
             __Pyx_GIVEREF(__pyx_v_fst_type);
             PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_fst_type);
-            __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_6);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           }
@@ -29366,14 +29178,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
           }
         }
         if (!__pyx_t_7) {
-          __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2668, __pyx_L1_error)
+          __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2743, __pyx_L1_error)
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_4);
         } else {
           #if CYTHON_FAST_PYCALL
           if (PyFunction_Check(__pyx_t_5)) {
             PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-            __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
             __Pyx_GOTREF(__pyx_t_4);
             __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -29382,20 +29194,20 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
           #if CYTHON_FAST_PYCCALL
           if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
             PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-            __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
             __Pyx_GOTREF(__pyx_t_4);
             __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
           } else
           #endif
           {
-            __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
             __Pyx_GIVEREF(__pyx_t_6);
             PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
             __pyx_t_6 = 0;
-            __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2668, __pyx_L1_error)
+            __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2743, __pyx_L1_error)
             __Pyx_GOTREF(__pyx_t_4);
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           }
@@ -29403,9 +29215,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
         __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, 2668, __pyx_L1_error)
+        __PYX_ERR(0, 2743, __pyx_L1_error)
 
-        /* "pywrapfst.pyx":2667
+        /* "pywrapfst.pyx":2742
  *     if fst_type_string != ofst.FstType():
  *       ofst = fst.Convert(deref(ofst), fst_type_string)
  *       if ofst == NULL:             # <<<<<<<<<<<<<<
@@ -29414,7 +29226,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
  */
       }
 
-      /* "pywrapfst.pyx":2665
+      /* "pywrapfst.pyx":2740
  *   if fst_type is not None:
  *     fst_type_string = tostring(fst_type)
  *     if fst_type_string != ofst.FstType():             # <<<<<<<<<<<<<<
@@ -29423,7 +29235,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
  */
     }
 
-    /* "pywrapfst.pyx":2663
+    /* "pywrapfst.pyx":2738
  * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
  *   ofst = fst.FstClass.ReadFromString(fst_string)
  *   if fst_type is not None:             # <<<<<<<<<<<<<<
@@ -29432,22 +29244,22 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
  */
   }
 
-  /* "pywrapfst.pyx":2669
+  /* "pywrapfst.pyx":2744
  *       if ofst == NULL:
  *         raise FstOpError("Conversion to {!r} failed.".format(fst_type))
  *   return _init_XFst(ofst)             # <<<<<<<<<<<<<<
  * 
- * class Fst(object):
+ * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_ofst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2669, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_ofst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2744, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2661
- *   return _init_XFst(tfst)
+  /* "pywrapfst.pyx":2736
+ * 
  * 
  * cdef _Fst _deserialize_Fst(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
  *   ofst = fst.FstClass.ReadFromString(fst_string)
@@ -29470,7 +29282,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__deserialize_Fst(PyO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2688
+/* "pywrapfst.pyx":2764
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29512,7 +29324,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, 2688, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) __PYX_ERR(0, 2764, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29527,7 +29339,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, 2688, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2764, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29547,7 +29359,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":2689
+  /* "pywrapfst.pyx":2765
  * 
  *    def __new__(cls, arc_type=b"standard"):
  *     return _create_Fst(arc_type)             # <<<<<<<<<<<<<<
@@ -29557,13 +29369,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, 2689, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__create_Fst(&__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2765, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2688
+  /* "pywrapfst.pyx":2764
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
@@ -29582,7 +29394,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2692
+/* "pywrapfst.pyx":2768
  * 
  *    @staticmethod
  *    def read(filename, fst_type=None):             # <<<<<<<<<<<<<<
@@ -29625,7 +29437,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read") < 0)) __PYX_ERR(0, 2692, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read") < 0)) __PYX_ERR(0, 2768, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29640,7 +29452,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2692, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2768, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29660,7 +29472,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   struct __pyx_opt_args_9pywrapfst__read_Fst __pyx_t_2;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":2710
+  /* "pywrapfst.pyx":2786
  *        FstOpError: Read-time conversion failed.
  *      """
  *      return _read_Fst(filename, fst_type)             # <<<<<<<<<<<<<<
@@ -29670,13 +29482,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   __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__read_Fst(__pyx_v_filename, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2710, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_filename, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2786, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2692
+  /* "pywrapfst.pyx":2768
  * 
  *    @staticmethod
  *    def read(filename, fst_type=None):             # <<<<<<<<<<<<<<
@@ -29695,7 +29507,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2713
+/* "pywrapfst.pyx":2789
  * 
  *    @staticmethod
  *    def read_from_string(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
@@ -29705,7 +29517,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_se
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_4read_from_string[] = "\n     read_from_string(fst_string, fst_type=None)\n\n     Reads an FST from a string.\n\n     Args:\n       fst_string: The string containing the serialized Fst.\n       fst_type: A string indicating the FST type to convert to; no conversion\n         is performed if omitted or if the FST is already of the desired type.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n       FstOpError: Read-time conversion failed.\n     ";
+static char __pyx_doc_9pywrapfst_3Fst_4read_from_string[] = "\n     read_from_string(fst_string, fst_type=None)\n\n     Reads an FST from a serialized string.\n\n     Args:\n       fst_string: The string containing the serialized FST.\n       fst_type: A string indicating the FST type to convert to; no conversion\n         is performed if omitted or if the FST is already of the desired type.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n       FstOpError: Read-time conversion failed.\n\n     See also: `write_to_string`.\n     ";
 static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_5read_from_string = {"read_from_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_5read_from_string, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_3Fst_4read_from_string};
 static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_fst_string = 0;
@@ -29738,7 +29550,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 2713, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 2789, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29753,7 +29565,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_from_string", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2713, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_from_string", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2789, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29773,23 +29585,23 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   struct __pyx_opt_args_9pywrapfst__deserialize_Fst __pyx_t_2;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":2731
- *        FstOpError: Read-time conversion failed.
+  /* "pywrapfst.pyx":2809
+ *      See also: `write_to_string`.
  *      """
  *      return _deserialize_Fst(fst_string, fst_type)             # <<<<<<<<<<<<<<
  * 
- * ## FST properties.
+ * 
  */
   __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__deserialize_Fst(__pyx_v_fst_string, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2731, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__deserialize_Fst(__pyx_v_fst_string, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2809, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2713
+  /* "pywrapfst.pyx":2789
  * 
  *    @staticmethod
  *    def read_from_string(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
@@ -29808,7 +29620,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2815
+/* "pywrapfst.pyx":2914
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29839,7 +29651,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":2816
+  /* "pywrapfst.pyx":2915
  * 
  *   def __repr__(self):
  *     return "<Arc at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -29847,14 +29659,14 @@ 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_s_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -29868,14 +29680,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2816, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2816, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -29884,20 +29696,20 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2816, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2816, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2915, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2816, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2915, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -29907,7 +29719,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2815
+  /* "pywrapfst.pyx":2914
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -29930,7 +29742,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2818
+/* "pywrapfst.pyx":2917
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -29970,21 +29782,21 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_olabel)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 2818, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 2917, __pyx_L3_error)
         }
         case  2:
         if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 2818, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 2917, __pyx_L3_error)
         }
         case  3:
         if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nextstate)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 2818, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 2917, __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, 2818, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2917, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -29994,14 +29806,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, 2818, __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, 2818, __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, 2917, __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, 2917, __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, 2818, __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, 2917, __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, 2818, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2917, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -30022,18 +29834,18 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   fst::script::WeightClass __pyx_t_2;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2819
+  /* "pywrapfst.pyx":2918
  * 
  *   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_convert_string_from_py_std__in_string(__pyx_n_b_tropical); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2819, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_t_1, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2819, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_tropical); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2918, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_t_1, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2918, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_2;
 
-  /* "pywrapfst.pyx":2820
+  /* "pywrapfst.pyx":2919
  *   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))             # <<<<<<<<<<<<<<
@@ -30042,11 +29854,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 '%s'", "_arc");
-    __PYX_ERR(0, 2820, __pyx_L1_error)
+    __PYX_ERR(0, 2919, __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":2818
+  /* "pywrapfst.pyx":2917
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -30065,7 +29877,7 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2822
+/* "pywrapfst.pyx":2921
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -30087,7 +29899,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2822, __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, 2921, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_3Arc_5copy)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -30103,14 +29915,14 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2822, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2921, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2822, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2921, __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, 2822, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 2921, __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;
@@ -30119,7 +29931,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2823
+  /* "pywrapfst.pyx":2922
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -30127,15 +29939,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, 2823, __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, 2922, __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, 2823, __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, 2922, __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, 2823, __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, 2922, __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, 2823, __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, 2922, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2823, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2922, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -30149,14 +29961,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, 2823, __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, 2922, __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":2822
+  /* "pywrapfst.pyx":2921
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -30198,7 +30010,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, 2822, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2921, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30215,7 +30027,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2827
+/* "pywrapfst.pyx":2926
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30242,7 +30054,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2828
+  /* "pywrapfst.pyx":2927
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -30252,15 +30064,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 '%s'", "_arc");
-    __PYX_ERR(0, 2828, __pyx_L1_error)
+    __PYX_ERR(0, 2927, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2828, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2927, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2827
+  /* "pywrapfst.pyx":2926
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30279,7 +30091,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2830
+/* "pywrapfst.pyx":2929
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30295,7 +30107,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, 2830, __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, 2929, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30315,7 +30127,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2831
+  /* "pywrapfst.pyx":2930
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -30324,11 +30136,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 '%s'", "_arc");
-    __PYX_ERR(0, 2831, __pyx_L1_error)
+    __PYX_ERR(0, 2930, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2830
+  /* "pywrapfst.pyx":2929
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30347,7 +30159,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2835
+/* "pywrapfst.pyx":2934
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30374,7 +30186,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2836
+  /* "pywrapfst.pyx":2935
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -30384,15 +30196,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 '%s'", "_arc");
-    __PYX_ERR(0, 2836, __pyx_L1_error)
+    __PYX_ERR(0, 2935, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2836, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2935, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2835
+  /* "pywrapfst.pyx":2934
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30411,7 +30223,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2838
+/* "pywrapfst.pyx":2937
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30427,7 +30239,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, 2838, __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, 2937, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30447,7 +30259,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2839
+  /* "pywrapfst.pyx":2938
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -30456,11 +30268,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 '%s'", "_arc");
-    __PYX_ERR(0, 2839, __pyx_L1_error)
+    __PYX_ERR(0, 2938, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2838
+  /* "pywrapfst.pyx":2937
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30479,7 +30291,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2843
+/* "pywrapfst.pyx":2942
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30507,20 +30319,20 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2844
+  /* "pywrapfst.pyx":2943
  * 
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2844, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2943, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 2844, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 2943, __pyx_L1_error)
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2845
+  /* "pywrapfst.pyx":2944
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
@@ -30529,15 +30341,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 '%s'", "_weight");
-    __PYX_ERR(0, 2845, __pyx_L1_error)
+    __PYX_ERR(0, 2944, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc");
-    __PYX_ERR(0, 2845, __pyx_L1_error)
+    __PYX_ERR(0, 2944, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":2846
+  /* "pywrapfst.pyx":2945
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight             # <<<<<<<<<<<<<<
@@ -30549,7 +30361,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2843
+  /* "pywrapfst.pyx":2942
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30569,7 +30381,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2848
+/* "pywrapfst.pyx":2947
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30597,22 +30409,22 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   fst::script::WeightClass __pyx_t_2;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2849
+  /* "pywrapfst.pyx":2948
  * 
  *     def __set__(self, weight):
  *       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
  * 
  *   property nextstate:
  */
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_tropical); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2849, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_t_1, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2849, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_tropical); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2948, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_t_1, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2948, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc");
-    __PYX_ERR(0, 2849, __pyx_L1_error)
+    __PYX_ERR(0, 2948, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_2;
 
-  /* "pywrapfst.pyx":2848
+  /* "pywrapfst.pyx":2947
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -30631,7 +30443,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2853
+/* "pywrapfst.pyx":2952
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30658,7 +30470,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":2854
+  /* "pywrapfst.pyx":2953
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -30668,15 +30480,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 '%s'", "_arc");
-    __PYX_ERR(0, 2854, __pyx_L1_error)
+    __PYX_ERR(0, 2953, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2854, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2953, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2853
+  /* "pywrapfst.pyx":2952
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -30695,7 +30507,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2856
+/* "pywrapfst.pyx":2955
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30711,7 +30523,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, 2856, __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, 2955, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -30731,7 +30543,7 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":2857
+  /* "pywrapfst.pyx":2956
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -30740,11 +30552,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 '%s'", "_arc");
-    __PYX_ERR(0, 2857, __pyx_L1_error)
+    __PYX_ERR(0, 2956, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":2856
+  /* "pywrapfst.pyx":2955
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -30763,7 +30575,7 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2860
+/* "pywrapfst.pyx":2959
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -30781,20 +30593,20 @@ 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":2861
+  /* "pywrapfst.pyx":2960
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(<int64> arc.ilabel, <int64> arc.olabel, weight,
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2861, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2960, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 2861, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_Weight)))) __PYX_ERR(0, 2960, __pyx_L1_error)
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2862
+  /* "pywrapfst.pyx":2961
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
@@ -30803,11 +30615,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 '%s'", "_weight");
-    __PYX_ERR(0, 2862, __pyx_L1_error)
+    __PYX_ERR(0, 2961, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":2863
+  /* "pywrapfst.pyx":2962
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(<int64> arc.ilabel, <int64> arc.olabel, weight,             # <<<<<<<<<<<<<<
@@ -30815,29 +30627,29 @@ 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_t_10basictypes_int64)__pyx_v_arc.ilabel)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(((__pyx_t_10basictypes_int64)__pyx_v_arc.ilabel)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2962, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(((__pyx_t_10basictypes_int64)__pyx_v_arc.olabel)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(((__pyx_t_10basictypes_int64)__pyx_v_arc.olabel)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2962, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":2864
+  /* "pywrapfst.pyx":2963
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(<int64> arc.ilabel, <int64> arc.olabel, weight,
  *              <int64> arc.nextstate)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(((__pyx_t_10basictypes_int64)__pyx_v_arc.nextstate)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2864, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(((__pyx_t_10basictypes_int64)__pyx_v_arc.nextstate)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2963, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2863
+  /* "pywrapfst.pyx":2962
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))
  *   return Arc(<int64> arc.ilabel, <int64> arc.olabel, weight,             # <<<<<<<<<<<<<<
  *              <int64> arc.nextstate)
  * 
  */
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2962, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
@@ -30851,14 +30663,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, 2863, __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, 2962, __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":2860
+  /* "pywrapfst.pyx":2959
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -30881,7 +30693,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2877
+/* "pywrapfst.pyx":2974
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -30912,7 +30724,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":2878
+  /* "pywrapfst.pyx":2975
  * 
  *   def __repr__(self):
  *     return "<ArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -30920,14 +30732,14 @@ 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_s_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2878, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2878, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2878, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -30941,14 +30753,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -30957,20 +30769,20 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2878, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2975, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2878, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -30980,7 +30792,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2877
+  /* "pywrapfst.pyx":2974
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -31003,7 +30815,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2880
+/* "pywrapfst.pyx":2977
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -31039,11 +30851,11 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 2880, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 2977, __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, 2880, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2977, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -31052,17 +30864,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, 2880, __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, 2977, __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, 2880, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2977, __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, 2880, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 2977, __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 */
@@ -31083,7 +30895,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   std::shared_ptr<fst::script::FstClass>  __pyx_t_4;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2881
+  /* "pywrapfst.pyx":2978
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31092,28 +30904,28 @@ 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 '%s'", "_fst");
-    __PYX_ERR(0, 2881, __pyx_L1_error)
+    __PYX_ERR(0, 2978, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2882
+    /* "pywrapfst.pyx":2979
  *   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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2882, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2979, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2882, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2979, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2882, __pyx_L1_error)
+    __PYX_ERR(0, 2979, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2881
+    /* "pywrapfst.pyx":2978
  * 
  *   def __init__(self, _Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -31122,7 +30934,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":2884
+  /* "pywrapfst.pyx":2981
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -31131,16 +30943,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 '%s'", "_fst");
-    __PYX_ERR(0, 2884, __pyx_L1_error)
+    __PYX_ERR(0, 2981, __pyx_L1_error)
   }
   __pyx_t_4 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 2884, __pyx_L1_error)
+    __PYX_ERR(0, 2981, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_4;
 
-  /* "pywrapfst.pyx":2885
+  /* "pywrapfst.pyx":2982
  *     # 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))             # <<<<<<<<<<<<<<
@@ -31149,15 +30961,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2885, __pyx_L1_error)
+    __PYX_ERR(0, 2982, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 2885, __pyx_L1_error)
+    __PYX_ERR(0, 2982, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":2880
+  /* "pywrapfst.pyx":2977
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -31178,7 +30990,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2888
+/* "pywrapfst.pyx":2985
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31204,7 +31016,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":2889
+  /* "pywrapfst.pyx":2986
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -31216,7 +31028,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2888
+  /* "pywrapfst.pyx":2985
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -31231,7 +31043,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2892
+/* "pywrapfst.pyx":2989
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31260,7 +31072,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":2893
+  /* "pywrapfst.pyx":2990
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31269,12 +31081,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 '%s'", "done");
-    __PYX_ERR(0, 2893, __pyx_L1_error)
+    __PYX_ERR(0, 2990, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2894
+    /* "pywrapfst.pyx":2991
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -31282,9 +31094,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, 2894, __pyx_L1_error)
+    __PYX_ERR(0, 2991, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2893
+    /* "pywrapfst.pyx":2990
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -31293,7 +31105,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2895
+  /* "pywrapfst.pyx":2992
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -31302,14 +31114,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 '%s'", "value");
-    __PYX_ERR(0, 2895, __pyx_L1_error)
+    __PYX_ERR(0, 2992, __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, 2895, __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, 2992, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2896
+  /* "pywrapfst.pyx":2993
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -31318,11 +31130,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 '%s'", "next");
-    __PYX_ERR(0, 2896, __pyx_L1_error)
+    __PYX_ERR(0, 2993, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":2897
+  /* "pywrapfst.pyx":2994
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -31334,7 +31146,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2892
+  /* "pywrapfst.pyx":2989
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -31354,7 +31166,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2899
+/* "pywrapfst.pyx":2996
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31376,7 +31188,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2899, __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, 2996, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_9done)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -31391,14 +31203,14 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2899, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2899, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __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, 2899, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2996, __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;
@@ -31407,7 +31219,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2911
+  /* "pywrapfst.pyx":3005
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -31416,12 +31228,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2911, __pyx_L1_error)
+    __PYX_ERR(0, 3005, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2899
+  /* "pywrapfst.pyx":2996
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -31444,7 +31256,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -31462,7 +31274,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, 2899, __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, 2996, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31479,7 +31291,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2913
+/* "pywrapfst.pyx":3007
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -31501,7 +31313,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2913, __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, 3007, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_11flags)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -31516,14 +31328,14 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2913, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3007, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2913, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3007, __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, 2913, __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, 3007, __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;
@@ -31532,7 +31344,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2925
+  /* "pywrapfst.pyx":3016
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -31541,12 +31353,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2925, __pyx_L1_error)
+    __PYX_ERR(0, 3016, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2913
+  /* "pywrapfst.pyx":3007
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -31569,7 +31381,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_10flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_10flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -31587,7 +31399,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, 2913, __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, 3007, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31604,7 +31416,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2927
+/* "pywrapfst.pyx":3018
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31624,7 +31436,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2927, __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, 3018, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_13next)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -31639,10 +31451,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2927, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3018, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2927, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3018, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -31653,8 +31465,8 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2936
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3024
+ *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
  * 
@@ -31662,11 +31474,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2936, __pyx_L1_error)
+    __PYX_ERR(0, 3024, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":2927
+  /* "pywrapfst.pyx":3018
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -31688,7 +31500,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_12next[] = "\n    next(self)\n\n    Advances the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_12next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -31706,7 +31518,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, 2927, __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, 3018, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31723,12 +31535,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2938
+/* "pywrapfst.pyx":3026
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
  *     """
- *     next(self)
+ *     position(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -31745,7 +31557,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2938, __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, 3026, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_15position)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -31760,14 +31572,14 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2938, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3026, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2938, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3026, __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, 2938, __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, 3026, __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;
@@ -31776,7 +31588,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2950
+  /* "pywrapfst.pyx":3035
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -31785,17 +31597,17 @@ 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 '%s'", "_aiter");
-    __PYX_ERR(0, 2950, __pyx_L1_error)
+    __PYX_ERR(0, 3035, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2938
+  /* "pywrapfst.pyx":3026
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
  *     """
- *     next(self)
+ *     position(self)
  */
 
   /* function exit code */
@@ -31813,7 +31625,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_14position[] = "\n    next(self)\n\n    Returns the position of the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_14position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -31831,7 +31643,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, 2938, __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, 3026, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31848,7 +31660,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2952
+/* "pywrapfst.pyx":3037
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -31868,7 +31680,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2952, __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, 3037, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_17reset)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -31883,10 +31695,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2952, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3037, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2952, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3037, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -31897,8 +31709,8 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2961
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3043
+ *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
  * 
@@ -31906,11 +31718,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2961, __pyx_L1_error)
+    __PYX_ERR(0, 3043, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":2952
+  /* "pywrapfst.pyx":3037
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -31932,7 +31744,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_16reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_16reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -31950,7 +31762,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, 2952, __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, 3037, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31967,7 +31779,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2963
+/* "pywrapfst.pyx":3045
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -31989,10 +31801,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2963, __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, 3045, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_19seek)) {
-      __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2963, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3045, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -32006,14 +31818,14 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2963, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3045, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2963, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3045, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -32022,20 +31834,20 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2963, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3045, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2963, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3045, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2963, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3045, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -32048,7 +31860,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2975
+  /* "pywrapfst.pyx":3054
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -32057,11 +31869,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2975, __pyx_L1_error)
+    __PYX_ERR(0, 3054, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":2963
+  /* "pywrapfst.pyx":3045
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -32085,14 +31897,14 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      a: The position to seek to.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
   PyObject *__pyx_r = 0;
   __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, 2963, __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, 3045, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -32113,7 +31925,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, 2963, __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, 3045, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32130,7 +31942,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2977
+/* "pywrapfst.pyx":3056
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -32154,12 +31966,12 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2977, __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, 3056, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__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, 2977, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3056, __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, 2977, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3056, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -32177,7 +31989,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, 2977, __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, 3056, __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;
@@ -32187,7 +31999,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, 2977, __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, 3056, __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;
@@ -32195,7 +32007,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, 2977, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3056, __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;
@@ -32206,7 +32018,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, 2977, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3056, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -32218,7 +32030,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":2990
+  /* "pywrapfst.pyx":3066
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -32227,11 +32039,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 '%s'", "_aiter");
-    __PYX_ERR(0, 2990, __pyx_L1_error)
+    __PYX_ERR(0, 3066, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":3056
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -32256,7 +32068,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_uint32 __pyx_v_flags;
   __pyx_t_10basictypes_uint32 __pyx_v_mask;
@@ -32283,11 +32095,11 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 2977, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3056, __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, 2977, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3056, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32295,12 +32107,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, 2977, __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, 2977, __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, 3056, __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, 3056, __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, 2977, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3056, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -32319,7 +32131,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, 2977, __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, 3056, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32336,7 +32148,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2992
+/* "pywrapfst.pyx":3068
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32357,7 +32169,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2992, __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, 3068, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_11ArcIterator_23value)) {
       __Pyx_XDECREF(__pyx_r);
@@ -32373,10 +32185,10 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2992, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3068, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2992, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3068, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -32388,8 +32200,8 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3001
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3074
+ *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
  * 
@@ -32398,15 +32210,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3001, __pyx_L1_error)
+    __PYX_ERR(0, 3074, __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, 3001, __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, 3074, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2992
+  /* "pywrapfst.pyx":3068
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -32430,7 +32242,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11ArcIterator_22value[] = "\n    value(self)\n\n    Returns the current arc, represented as a tuple.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_11ArcIterator_22value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_23value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -32448,7 +32260,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, 2992, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3068, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32465,7 +32277,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3015
+/* "pywrapfst.pyx":3086
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32496,7 +32308,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3016
+  /* "pywrapfst.pyx":3087
  * 
  *   def __repr__(self):
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -32504,14 +32316,14 @@ 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_s_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3087, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3087, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3087, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -32525,14 +32337,14 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3016, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3087, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3016, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3087, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -32541,20 +32353,20 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3016, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3087, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3016, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3087, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3016, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3087, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -32564,7 +32376,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3015
+  /* "pywrapfst.pyx":3086
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32587,7 +32399,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3018
+/* "pywrapfst.pyx":3089
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -32623,11 +32435,11 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3018, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 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, "__init__") < 0)) __PYX_ERR(0, 3018, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3089, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32636,17 +32448,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, 3018, __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, 3089, __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, 3018, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3089, __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, 3018, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3089, __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 */
@@ -32667,7 +32479,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   std::shared_ptr<fst::script::MutableFstClass>  __pyx_t_4;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3019
+  /* "pywrapfst.pyx":3090
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32676,28 +32488,28 @@ 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 '%s'", "_fst");
-    __PYX_ERR(0, 3019, __pyx_L1_error)
+    __PYX_ERR(0, 3090, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":3020
+    /* "pywrapfst.pyx":3091
  *   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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3020, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3091, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3020, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3091, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3020, __pyx_L1_error)
+    __PYX_ERR(0, 3091, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3019
+    /* "pywrapfst.pyx":3090
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32706,7 +32518,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":3022
+  /* "pywrapfst.pyx":3093
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -32715,33 +32527,33 @@ 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 '%s'", "_mfst");
-    __PYX_ERR(0, 3022, __pyx_L1_error)
+    __PYX_ERR(0, 3093, __pyx_L1_error)
   }
   __pyx_t_4 = __pyx_v_ifst->_mfst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 3022, __pyx_L1_error)
+    __PYX_ERR(0, 3093, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_4;
 
-  /* "pywrapfst.pyx":3023
+  /* "pywrapfst.pyx":3094
  *     # 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))             # <<<<<<<<<<<<<<
  * 
- *   # This just registers this class as a possible iterator.
+ *   cpdef bool done(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_aiter");
-    __PYX_ERR(0, 3023, __pyx_L1_error)
+    __PYX_ERR(0, 3094, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_mfst");
-    __PYX_ERR(0, 3023, __pyx_L1_error)
+    __PYX_ERR(0, 3094, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3018
+  /* "pywrapfst.pyx":3089
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
@@ -32762,191 +32574,15 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3026
- * 
- *   # This just registers this class as a possible iterator.
- *   def __iter__(self):             # <<<<<<<<<<<<<<
- *     return self
- * 
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__(PyObject *__pyx_v_self) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__iter__", 0);
-
-  /* "pywrapfst.pyx":3027
- *   # This just registers this class as a possible iterator.
- *   def __iter__(self):
- *     return self             # <<<<<<<<<<<<<<
- * 
- *   # Magic method used to get a Pythonic API out of the C++ API.
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_self));
-  __pyx_r = ((PyObject *)__pyx_v_self);
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":3026
- * 
- *   # This just registers this class as a possible iterator.
- *   def __iter__(self):             # <<<<<<<<<<<<<<
- *     return self
- * 
- */
-
-  /* function exit code */
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":3030
- * 
- *   # Magic method used to get a Pythonic API out of the C++ API.
- *   def __next__(self):             # <<<<<<<<<<<<<<
- *     if self.done():
- *       raise StopIteration
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_7__next__(PyObject *__pyx_v_self) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_6__next__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_6__next__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
-  PyObject *__pyx_v_result = NULL;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  __Pyx_RefNannySetupContext("__next__", 0);
-
-  /* "pywrapfst.pyx":3031
- *   # Magic method used to get a Pythonic API out of the C++ API.
- *   def __next__(self):
- *     if self.done():             # <<<<<<<<<<<<<<
- *       raise StopIteration
- *     result = self.value()
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "done");
-    __PYX_ERR(0, 3031, __pyx_L1_error)
-  }
-  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
-  if (__pyx_t_1) {
-
-    /* "pywrapfst.pyx":3032
- *   def __next__(self):
- *     if self.done():
- *       raise StopIteration             # <<<<<<<<<<<<<<
- *     result = self.value()
- *     self.next()
- */
-    __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 3032, __pyx_L1_error)
-
-    /* "pywrapfst.pyx":3031
- *   # Magic method used to get a Pythonic API out of the C++ API.
- *   def __next__(self):
- *     if self.done():             # <<<<<<<<<<<<<<
- *       raise StopIteration
- *     result = self.value()
- */
-  }
-
-  /* "pywrapfst.pyx":3033
- *     if self.done():
- *       raise StopIteration
- *     result = self.value()             # <<<<<<<<<<<<<<
- *     self.next()
- *     return result
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "value");
-    __PYX_ERR(0, 3033, __pyx_L1_error)
-  }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3033, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_v_result = __pyx_t_2;
-  __pyx_t_2 = 0;
-
-  /* "pywrapfst.pyx":3034
- *       raise StopIteration
- *     result = self.value()
- *     self.next()             # <<<<<<<<<<<<<<
- *     return result
- * 
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "next");
-    __PYX_ERR(0, 3034, __pyx_L1_error)
-  }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
-
-  /* "pywrapfst.pyx":3035
- *     result = self.value()
- *     self.next()
- *     return result             # <<<<<<<<<<<<<<
- * 
- *   cpdef bool done(self):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(__pyx_v_result);
-  __pyx_r = __pyx_v_result;
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":3030
- * 
- *   # Magic method used to get a Pythonic API out of the C++ API.
- *   def __next__(self):             # <<<<<<<<<<<<<<
- *     if self.done():
- *       raise StopIteration
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_result);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":3037
- *     return result
+/* "pywrapfst.pyx":3096
+ *     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
  *     """
  *     done(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -32960,9 +32596,9 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3037, __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, 3096, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_9done)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_5done)) {
       __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))) {
@@ -32975,14 +32611,14 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3037, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3096, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3037, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3096, __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, 3037, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3096, __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;
@@ -32991,7 +32627,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3049
+  /* "pywrapfst.pyx":3105
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -33000,13 +32636,13 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_aiter");
-    __PYX_ERR(0, 3049, __pyx_L1_error)
+    __PYX_ERR(0, 3105, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3037
- *     return result
+  /* "pywrapfst.pyx":3096
+ *     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
  *     """
@@ -33027,26 +32663,26 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_4done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_5done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("done (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_8done(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_4done(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3037, __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, 3096, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33063,7 +32699,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3051
+/* "pywrapfst.pyx":3107
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -33071,7 +32707,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8done(struct __pyx_obj
  *     flags(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_7flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __pyx_t_10basictypes_uint32 __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -33085,9 +32721,9 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3051, __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, 3107, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_11flags)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_7flags)) {
       __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))) {
@@ -33100,14 +32736,14 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3051, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3107, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3051, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3107, __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, 3051, __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, 3107, __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;
@@ -33116,7 +32752,7 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3063
+  /* "pywrapfst.pyx":3116
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -33125,12 +32761,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3063, __pyx_L1_error)
+    __PYX_ERR(0, 3116, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3051
+  /* "pywrapfst.pyx":3107
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint32 flags(self):             # <<<<<<<<<<<<<<
@@ -33152,26 +32788,26 @@ static __pyx_t_10basictypes_uint32 __pyx_f_9pywrapfst_18MutableArcIterator_flags
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_10flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_7flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_6flags[] = "\n    flags(self)\n\n    Returns the current iterator behavioral flags.\n\n    Returns:\n      The current iterator behavioral flags as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_7flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("flags (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_10flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_6flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_6flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3051, __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, 3107, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33188,7 +32824,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10flags(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3065
+/* "pywrapfst.pyx":3118
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33196,7 +32832,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10flags(struct __pyx_o
  *     next(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33208,9 +32844,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3065, __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, 3118, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_13next)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_9next)) {
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33223,10 +32859,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3065, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3118, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3065, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3118, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33237,8 +32873,8 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3074
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3124
+ *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
  * 
@@ -33246,11 +32882,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3074, __pyx_L1_error)
+    __PYX_ERR(0, 3124, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3065
+  /* "pywrapfst.pyx":3118
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33271,26 +32907,26 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_12next[] = "\n    next(self)\n\n    Advances the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_8next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_9next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("next (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_12next(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_8next(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_12next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_8next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3065, __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, 3118, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33307,15 +32943,15 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_12next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3076
+/* "pywrapfst.pyx":3126
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
  *     """
- *     next(self)
+ *     position(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -33329,9 +32965,9 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3076, __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, 3126, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_15position)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_11position)) {
       __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))) {
@@ -33344,14 +32980,14 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3076, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3126, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3076, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3126, __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, 3076, __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, 3126, __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;
@@ -33360,7 +32996,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3088
+  /* "pywrapfst.pyx":3135
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -33369,17 +33005,17 @@ 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 '%s'", "_aiter");
-    __PYX_ERR(0, 3088, __pyx_L1_error)
+    __PYX_ERR(0, 3135, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3076
+  /* "pywrapfst.pyx":3126
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
  *     """
- *     next(self)
+ *     position(self)
  */
 
   /* function exit code */
@@ -33396,26 +33032,26 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_14position[] = "\n    next(self)\n\n    Returns the position of the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_10position[] = "\n    position(self)\n\n    Returns the position of the iterator.\n\n    Returns:\n      The iterator's position, expressed as an integer.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_11position(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("position (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_14position(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_10position(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_10position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3076, __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, 3126, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33432,7 +33068,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3090
+/* "pywrapfst.pyx":3137
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33440,7 +33076,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14position(struct __py
  *     reset(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33452,9 +33088,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3090, __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, 3137, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_17reset)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_13reset)) {
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33467,10 +33103,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3090, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3137, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3090, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3137, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33481,8 +33117,8 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3099
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3143
+ *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
  * 
@@ -33490,11 +33126,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3099, __pyx_L1_error)
+    __PYX_ERR(0, 3143, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3090
+  /* "pywrapfst.pyx":3137
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33515,26 +33151,26 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_16reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reset (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_16reset(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_12reset(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_12reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3090, __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, 3137, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33551,7 +33187,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3101
+/* "pywrapfst.pyx":3145
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33559,7 +33195,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16reset(struct __pyx_o
  *     seek(self, a)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33573,10 +33209,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3101, __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, 3145, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_19seek)) {
-      __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3101, __pyx_L1_error)
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_15seek)) {
+      __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3145, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33590,14 +33226,14 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
         }
       }
       if (!__pyx_t_5) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3145, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3145, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33606,20 +33242,20 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3145, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3101, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3145, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3101, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3145, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -33632,7 +33268,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3113
+  /* "pywrapfst.pyx":3154
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -33641,11 +33277,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3113, __pyx_L1_error)
+    __PYX_ERR(0, 3154, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3101
+  /* "pywrapfst.pyx":3145
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33668,15 +33304,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      a: The position to seek to.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_14seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_15seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
   PyObject *__pyx_r = 0;
   __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, 3101, __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, 3145, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -33684,20 +33320,20 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19seek(PyObject *__pyx
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_18seek(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_14seek(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((size_t)__pyx_v_a));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_14seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3101, __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, 3145, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33714,7 +33350,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3115
+/* "pywrapfst.pyx":3156
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -33722,7 +33358,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18seek(struct __pyx_ob
  *     set_flags(self, flags, mask)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33738,12 +33374,12 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3115, __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, 3156, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags)) {
-      __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3115, __pyx_L1_error)
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_17set_flags)) {
+      __pyx_t_3 = __Pyx_PyInt_From_uint32_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3156, __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, 3115, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyInt_From_uint32_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3156, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -33761,7 +33397,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, 3115, __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, 3156, __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;
@@ -33771,7 +33407,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, 3115, __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, 3156, __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;
@@ -33779,7 +33415,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, 3115, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3156, __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;
@@ -33790,7 +33426,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, 3115, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3156, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -33802,7 +33438,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3128
+  /* "pywrapfst.pyx":3166
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -33811,11 +33447,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3128, __pyx_L1_error)
+    __PYX_ERR(0, 3166, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3115
+  /* "pywrapfst.pyx":3156
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint32 flags, uint32 mask):             # <<<<<<<<<<<<<<
@@ -33839,9 +33475,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_16set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_17set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   __pyx_t_10basictypes_uint32 __pyx_v_flags;
   __pyx_t_10basictypes_uint32 __pyx_v_mask;
   PyObject *__pyx_r = 0;
@@ -33867,11 +33503,11 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags(PyObject *
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3115, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3156, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3115, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3156, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -33879,31 +33515,31 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21set_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, 3115, __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, 3115, __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, 3156, __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, 3156, __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, 3115, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3156, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_20set_flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_16set_flags(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), __pyx_v_flags, __pyx_v_mask);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_16set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint32 __pyx_v_flags, __pyx_t_10basictypes_uint32 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3115, __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, 3156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33920,7 +33556,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3130
+/* "pywrapfst.pyx":3168
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -33928,7 +33564,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20set_flags(struct __p
  *     set_value(self, arc)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -33941,9 +33577,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3130, __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, 3168, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_19set_value)) {
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33956,13 +33592,13 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_arc)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3130, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_arc)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3168, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_arc)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3130, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3168, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -33970,19 +33606,19 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, ((PyObject *)__pyx_v_arc)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3130, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3168, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3130, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3168, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(((PyObject *)__pyx_v_arc));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_arc));
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, ((PyObject *)__pyx_v_arc));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3130, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3168, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -33995,7 +33631,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3139
+  /* "pywrapfst.pyx":3177
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -34004,15 +33640,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3139, __pyx_L1_error)
+    __PYX_ERR(0, 3177, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc");
-    __PYX_ERR(0, 3139, __pyx_L1_error)
+    __PYX_ERR(0, 3177, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3130
+  /* "pywrapfst.pyx":3168
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -34034,14 +33670,14 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_22set_value[] = "\n    set_value(self, arc)\n\n    Replace the current arc with a new arc.\n\n    Args:\n      arc: The arc to replace the current arc with.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_18set_value[] = "\n    set_value(self, arc)\n\n    Replace the current arc with a new arc.\n\n    Args:\n      arc: The arc to replace the current arc with.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_19set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc) {
   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, 3130, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_22set_value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3168, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_18set_value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
 
   /* function exit code */
   goto __pyx_L0;
@@ -34052,13 +33688,13 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_22set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_18set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 3130, __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, 3168, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34075,7 +33711,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_22set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3141
+/* "pywrapfst.pyx":3179
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34083,7 +33719,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_22set_value(struct __p
  *     value(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_25value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -34096,9 +33732,9 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3141, __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, 3179, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_25value)) {
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_21value)) {
       __Pyx_XDECREF(__pyx_r);
       __Pyx_INCREF(__pyx_t_1);
       __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -34112,10 +33748,10 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3141, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3179, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3141, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3179, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -34127,8 +33763,8 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3150
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3185
+ *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
  * 
@@ -34137,15 +33773,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 '%s'", "_aiter");
-    __PYX_ERR(0, 3150, __pyx_L1_error)
+    __PYX_ERR(0, 3185, __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, 3150, __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, 3185, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3141
+  /* "pywrapfst.pyx":3179
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -34168,26 +33804,26 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_25value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_18MutableArcIterator_24value[] = "\n    value(self)\n\n    Returns the current arc, represented as a tuple.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_25value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_18MutableArcIterator_20value[] = "\n    value(self)\n\n    Returns the current arc.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_21value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("value (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_24value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_20value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_24value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_20value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   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, 3141, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3179, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34204,7 +33840,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_24value(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3166
+/* "pywrapfst.pyx":3199
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34235,7 +33871,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3167
+  /* "pywrapfst.pyx":3200
  * 
  *   def __repr__(self):
  *     return "<StateIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -34243,14 +33879,14 @@ 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_s_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3167, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3200, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3167, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3200, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3167, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3200, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -34264,14 +33900,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
     }
   }
   if (!__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3167, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3167, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -34280,20 +33916,20 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_4};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3167, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3167, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3200, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
       __Pyx_GIVEREF(__pyx_t_4);
       PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
       __pyx_t_4 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3167, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
@@ -34303,7 +33939,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3166
+  /* "pywrapfst.pyx":3199
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -34326,7 +33962,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3169
+/* "pywrapfst.pyx":3202
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34359,7 +33995,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, 3169, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3202, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -34370,13 +34006,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, 3169, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3202, __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, 3169, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3202, __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 */
@@ -34394,7 +34030,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":3171
+  /* "pywrapfst.pyx":3204
  *   def __init__(self, _Fst ifst):
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -34403,16 +34039,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 '%s'", "_fst");
-    __PYX_ERR(0, 3171, __pyx_L1_error)
+    __PYX_ERR(0, 3204, __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 '%s'", "_fst");
-    __PYX_ERR(0, 3171, __pyx_L1_error)
+    __PYX_ERR(0, 3204, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3172
+  /* "pywrapfst.pyx":3205
  *     # 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)))             # <<<<<<<<<<<<<<
@@ -34421,15 +34057,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 '%s'", "_siter");
-    __PYX_ERR(0, 3172, __pyx_L1_error)
+    __PYX_ERR(0, 3205, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3172, __pyx_L1_error)
+    __PYX_ERR(0, 3205, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3169
+  /* "pywrapfst.pyx":3202
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
@@ -34448,7 +34084,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3175
+/* "pywrapfst.pyx":3208
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34474,7 +34110,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3176
+  /* "pywrapfst.pyx":3209
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -34486,7 +34122,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3175
+  /* "pywrapfst.pyx":3208
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34501,7 +34137,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3179
+/* "pywrapfst.pyx":3212
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -34530,7 +34166,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3180
+  /* "pywrapfst.pyx":3213
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34539,12 +34175,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 '%s'", "done");
-    __PYX_ERR(0, 3180, __pyx_L1_error)
+    __PYX_ERR(0, 3213, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":3181
+    /* "pywrapfst.pyx":3214
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -34552,9 +34188,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, 3181, __pyx_L1_error)
+    __PYX_ERR(0, 3214, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3180
+    /* "pywrapfst.pyx":3213
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -34563,7 +34199,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3182
+  /* "pywrapfst.pyx":3215
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -34572,11 +34208,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 '%s'", "value");
-    __PYX_ERR(0, 3182, __pyx_L1_error)
+    __PYX_ERR(0, 3215, __pyx_L1_error)
   }
   __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3183
+  /* "pywrapfst.pyx":3216
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -34585,11 +34221,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 '%s'", "next");
-    __PYX_ERR(0, 3183, __pyx_L1_error)
+    __PYX_ERR(0, 3216, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3184
+  /* "pywrapfst.pyx":3217
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -34597,13 +34233,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, 3184, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3217, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3179
+  /* "pywrapfst.pyx":3212
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -34622,7 +34258,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3186
+/* "pywrapfst.pyx":3219
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34644,7 +34280,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3186, __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, 3219, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_9done)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -34659,14 +34295,14 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3186, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3219, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3186, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3219, __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, 3186, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3219, __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;
@@ -34675,7 +34311,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3198
+  /* "pywrapfst.pyx":3228
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -34684,12 +34320,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 '%s'", "_siter");
-    __PYX_ERR(0, 3198, __pyx_L1_error)
+    __PYX_ERR(0, 3228, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3186
+  /* "pywrapfst.pyx":3219
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34712,7 +34348,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static char __pyx_doc_9pywrapfst_13StateIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -34730,7 +34366,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, 3186, __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, 3219, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34747,7 +34383,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3200
+/* "pywrapfst.pyx":3230
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34767,7 +34403,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3200, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3230, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_11next)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -34782,10 +34418,10 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3200, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3230, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3200, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3230, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -34796,8 +34432,8 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3209
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3236
+ *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
  * 
@@ -34805,11 +34441,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 '%s'", "_siter");
-    __PYX_ERR(0, 3209, __pyx_L1_error)
+    __PYX_ERR(0, 3236, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3200
+  /* "pywrapfst.pyx":3230
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34831,7 +34467,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_13StateIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -34849,7 +34485,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, 3200, __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, 3230, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34866,7 +34502,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3211
+/* "pywrapfst.pyx":3238
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -34886,7 +34522,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3211, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3238, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_13reset)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -34901,10 +34537,10 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3211, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3238, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3211, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3238, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -34915,8 +34551,8 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3220
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3244
+ *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
  * 
@@ -34924,11 +34560,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 '%s'", "_siter");
-    __PYX_ERR(0, 3220, __pyx_L1_error)
+    __PYX_ERR(0, 3244, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3211
+  /* "pywrapfst.pyx":3238
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -34950,7 +34586,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_13StateIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -34968,7 +34604,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, 3211, __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, 3238, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34985,7 +34621,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3222
+/* "pywrapfst.pyx":3246
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35007,7 +34643,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3222, __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, 3246, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_13StateIterator_15value)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -35022,14 +34658,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3222, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3246, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3222, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3246, __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, 3222, __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, 3246, __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;
@@ -35038,8 +34674,8 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":3231
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":3252
+ *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
  * 
@@ -35047,12 +34683,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 '%s'", "_siter");
-    __PYX_ERR(0, 3231, __pyx_L1_error)
+    __PYX_ERR(0, 3252, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3222
+  /* "pywrapfst.pyx":3246
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -35075,7 +34711,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_13StateIterator_14value[] = "\n    value(self)\n\n    Returns the current state index.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_13StateIterator_14value[] = "\n    value(self)\n\n    Returns the current state index.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -35093,7 +34729,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, 3222, __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, 3246, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35110,7 +34746,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3237
+/* "pywrapfst.pyx":3258
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35119,10 +34755,10 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
  */
 
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, struct __pyx_opt_args_9pywrapfst__map *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__34;
+  float __pyx_v_delta = __pyx_k__38;
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
 
-  /* "pywrapfst.pyx":3240
+  /* "pywrapfst.pyx":3261
  *                float delta=fst.kDelta,
  *                map_type=b"identity",
  *                weight=None):             # <<<<<<<<<<<<<<
@@ -35157,27 +34793,27 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
   }
 
-  /* "pywrapfst.pyx":3242
+  /* "pywrapfst.pyx":3263
  *                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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3242, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3263, __pyx_L1_error)
   __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v_map_type_enum)) != 0)) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3243
+    /* "pywrapfst.pyx":3264
  *   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_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3243, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3264, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3243, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3264, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_7 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
@@ -35190,13 +34826,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_map_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3243, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_map_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3264, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_map_type};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
@@ -35204,19 +34840,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_map_type};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_5);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_INCREF(__pyx_v_map_type);
         __Pyx_GIVEREF(__pyx_v_map_type);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_map_type);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -35233,14 +34869,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
       }
     }
     if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3243, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3264, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
@@ -35249,20 +34885,20 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
         PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
         __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
         __Pyx_GIVEREF(__pyx_t_5);
         PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
         __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3243, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3264, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
@@ -35270,9 +34906,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     __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, 3243, __pyx_L1_error)
+    __PYX_ERR(0, 3264, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3242
+    /* "pywrapfst.pyx":3263
  *                weight=None):
  *   cdef fst.MapType map_type_enum
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
@@ -35281,7 +34917,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":3245
+  /* "pywrapfst.pyx":3266
  *     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             # <<<<<<<<<<<<<<
@@ -35290,7 +34926,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":3244
+    /* "pywrapfst.pyx":3265
  *   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(),             # <<<<<<<<<<<<<<
@@ -35299,21 +34935,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 '%s'", "weight_type");
-      __PYX_ERR(0, 3244, __pyx_L1_error)
+      __PYX_ERR(0, 3265, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3245
+    /* "pywrapfst.pyx":3266
  *     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, wc))
  */
-    __pyx_t_10 = __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, 3244, __pyx_L1_error)
+    __pyx_t_10 = __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, 3265, __pyx_L1_error)
     __pyx_t_9 = __pyx_t_10;
   } else {
 
-    /* "pywrapfst.pyx":3246
+    /* "pywrapfst.pyx":3267
  *   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))             # <<<<<<<<<<<<<<
@@ -35322,14 +34958,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 '%s'", "weight_type");
-      __PYX_ERR(0, 3246, __pyx_L1_error)
+      __PYX_ERR(0, 3267, __pyx_L1_error)
     }
-    __pyx_t_10 = __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, 3246, __pyx_L1_error)
+    __pyx_t_10 = __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, 3267, __pyx_L1_error)
     __pyx_t_9 = __pyx_t_10;
   }
   __pyx_v_wc = __pyx_t_9;
 
-  /* "pywrapfst.pyx":3247
+  /* "pywrapfst.pyx":3268
  *       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, wc))             # <<<<<<<<<<<<<<
@@ -35339,15 +34975,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 '%s'", "_fst");
-    __PYX_ERR(0, 3247, __pyx_L1_error)
+    __PYX_ERR(0, 3268, __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_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3247, __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_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3268, __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":3237
+  /* "pywrapfst.pyx":3258
  * 
  * 
  * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35371,7 +35007,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3250
+/* "pywrapfst.pyx":3271
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35381,10 +35017,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
 
 static PyObject *__pyx_pw_9pywrapfst_13arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_arcmap *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__35;
+  float __pyx_v_delta = __pyx_k__39;
   PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
 
-  /* "pywrapfst.pyx":3253
+  /* "pywrapfst.pyx":3274
  *                   float delta=fst.kDelta,
  *                   map_type=b"identity",
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -35409,7 +35045,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3292
+  /* "pywrapfst.pyx":3313
  *   See also: `statemap`.
  *   """
  *   return _map(ifst, delta, map_type, weight)             # <<<<<<<<<<<<<<
@@ -35421,13 +35057,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_2.map_type = __pyx_v_map_type;
   __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, 3292, __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, 3313, __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":3250
+  /* "pywrapfst.pyx":3271
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35462,7 +35098,7 @@ static PyObject *__pyx_pw_9pywrapfst_13arcmap(PyObject *__pyx_self, PyObject *__
     PyObject* values[4] = {0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_identity);
 
-    /* "pywrapfst.pyx":3253
+    /* "pywrapfst.pyx":3274
  *                   float delta=fst.kDelta,
  *                   map_type=b"identity",
  *                   weight=None):             # <<<<<<<<<<<<<<
@@ -35503,7 +35139,7 @@ static PyObject *__pyx_pw_9pywrapfst_13arcmap(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, 3250, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3271, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -35517,25 +35153,25 @@ static PyObject *__pyx_pw_9pywrapfst_13arcmap(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, 3251, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3272, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__35;
+      __pyx_v_delta = __pyx_k__39;
     }
     __pyx_v_map_type = values[2];
     __pyx_v_weight = values[3];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3250, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3271, __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, 3250, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3271, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3250
+  /* "pywrapfst.pyx":3271
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -35563,7 +35199,7 @@ static PyObject *__pyx_pf_9pywrapfst_12arcmap(CYTHON_UNUSED PyObject *__pyx_self
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_2.map_type = __pyx_v_map_type;
   __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, 3250, __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, 3271, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35580,7 +35216,7 @@ static PyObject *__pyx_pf_9pywrapfst_12arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3295
+/* "pywrapfst.pyx":3316
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -35592,7 +35228,7 @@ static PyObject *__pyx_pw_9pywrapfst_15compose(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":3298
+  /* "pywrapfst.pyx":3319
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -35617,7 +35253,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
     }
   }
 
-  /* "pywrapfst.pyx":3322
+  /* "pywrapfst.pyx":3343
  *   See also: `arcsort`.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())             # <<<<<<<<<<<<<<
@@ -35626,21 +35262,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3322, __pyx_L1_error)
+    __PYX_ERR(0, 3343, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0));
 
-  /* "pywrapfst.pyx":3325
+  /* "pywrapfst.pyx":3346
  *   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, deref(opts))
  *   return _init_MutableFst(tfst)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3325, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3325, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3346, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3346, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3324
+  /* "pywrapfst.pyx":3345
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
@@ -35649,7 +35285,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   __pyx_v_opts.reset(new fst::script::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3326
+  /* "pywrapfst.pyx":3347
  *   opts.reset(new fst.ComposeOptions(connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -35658,15 +35294,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 '%s'", "_fst");
-    __PYX_ERR(0, 3326, __pyx_L1_error)
+    __PYX_ERR(0, 3347, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3326, __pyx_L1_error)
+    __PYX_ERR(0, 3347, __pyx_L1_error)
   }
   fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3327
+  /* "pywrapfst.pyx":3348
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -35674,13 +35310,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)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3327, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3348, __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":3295
+  /* "pywrapfst.pyx":3316
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -35701,7 +35337,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_15compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_14compose[] = "\n  compose(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively composes two FSTs.\n\n  This operation computes the composition of two FSTs. If A transduces string\n  x to y with weight a and B transduces y to z with weight b, then their\n  composition transduces string x to z with weight a \\otimes b. The output\n  labels of the first transducer or the input labels of the second transducer\n  must be sorted (or otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    A composed FST.\n\n  See also: `arcsort`.\n  ";
+static char __pyx_doc_9pywrapfst_14compose[] = "\n  compose(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively composes two FSTs.\n\n  This operation computes the composition of two FSTs. If A transduces string\n  x to y with weight a and B transduces y to z with weight b, then their\n  composition transduces string x to z with weight a \\otimes b. The output\n  labels of the first transducer or the input labels of the second transducer\n  must be sorted (or otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An FST.\n\n  See also: `arcsort`.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_15compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2 = 0;
@@ -35733,7 +35369,7 @@ static PyObject *__pyx_pw_9pywrapfst_15compose(PyObject *__pyx_self, PyObject *_
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3295, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3316, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -35747,7 +35383,7 @@ static PyObject *__pyx_pw_9pywrapfst_15compose(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, 3295, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3316, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -35763,10 +35399,10 @@ static PyObject *__pyx_pw_9pywrapfst_15compose(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, 3298, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3319, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3298
+      /* "pywrapfst.pyx":3319
  *                           _Fst ifst2,
  *                           compose_filter=b"auto",
  *                           bool connect=True):             # <<<<<<<<<<<<<<
@@ -35778,17 +35414,17 @@ static PyObject *__pyx_pw_9pywrapfst_15compose(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, 3295, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3316, __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, 3295, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3296, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3316, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3317, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_14compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3295
+  /* "pywrapfst.pyx":3316
  * 
  * 
  * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -35815,7 +35451,7 @@ static PyObject *__pyx_pf_9pywrapfst_14compose(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, 3295, __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, 3316, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35832,28 +35468,30 @@ static PyObject *__pyx_pf_9pywrapfst_14compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3330
+/* "pywrapfst.pyx":3351
  * 
  * 
- * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef _Fst convert(_Fst ifst, fst_type=None):             # <<<<<<<<<<<<<<
  *   """
- *   convert(ifst, fst_type="")
+ *   convert(ifst, fst_type=None)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_17convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args) {
-  PyObject *__pyx_v_fst_type = ((PyObject *)__pyx_kp_b_);
+  PyObject *__pyx_v_fst_type = ((PyObject *)Py_None);
+  std::string __pyx_v_fst_type_string;
   __pyx_t_9pywrapfst_FstClass_ptr __pyx_v_tfst;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
   __Pyx_RefNannySetupContext("convert", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -35861,35 +35499,42 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
   }
 
-  /* "pywrapfst.pyx":3347
+  /* "pywrapfst.pyx":3368
  *     FstOpError: Conversion failed.
  *   """
- *   cdef FstClass_ptr tfst = new fst.FstClass(deref(ifst._fst))             # <<<<<<<<<<<<<<
- *   tfst = fst.Convert(deref(ifst._fst), tostring(fst_type))
+ *   cdef string fst_type_string = "" if fst_type is None else tostring(fst_type)             # <<<<<<<<<<<<<<
+ *   cdef FstClass_ptr tfst = fst.Convert(deref(ifst._fst), fst_type_string)
  *   # Script-land Convert returns the null pointer to signal failure.
  */
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3347, __pyx_L1_error)
+  __pyx_t_2 = (__pyx_v_fst_type == Py_None);
+  if ((__pyx_t_2 != 0)) {
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b__5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3368, __pyx_L1_error)
+    __pyx_t_1 = __pyx_t_3;
+  } else {
+    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3368, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3368, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3368, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_1 = __pyx_t_3;
   }
-  __pyx_v_tfst = new fst::script::FstClass((*__pyx_v_ifst->_fst));
+  __pyx_v_fst_type_string = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3348
+  /* "pywrapfst.pyx":3369
  *   """
- *   cdef FstClass_ptr tfst = new fst.FstClass(deref(ifst._fst))
- *   tfst = fst.Convert(deref(ifst._fst), tostring(fst_type))             # <<<<<<<<<<<<<<
+ *   cdef string fst_type_string = "" if fst_type is None else tostring(fst_type)
+ *   cdef FstClass_ptr tfst = fst.Convert(deref(ifst._fst), fst_type_string)             # <<<<<<<<<<<<<<
  *   # Script-land Convert returns the null pointer to signal failure.
  *   if tfst == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3348, __pyx_L1_error)
+    __PYX_ERR(0, 3369, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3348, __pyx_L1_error)
-  __pyx_v_tfst = fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_t_1);
+  __pyx_v_tfst = fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v_fst_type_string);
 
-  /* "pywrapfst.pyx":3350
- *   tfst = fst.Convert(deref(ifst._fst), tostring(fst_type))
+  /* "pywrapfst.pyx":3371
+ *   cdef FstClass_ptr tfst = fst.Convert(deref(ifst._fst), fst_type_string)
  *   # Script-land Convert returns the null pointer to signal failure.
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
@@ -35898,112 +35543,112 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
   __pyx_t_2 = ((__pyx_v_tfst == NULL) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3351
+    /* "pywrapfst.pyx":3372
  *   # Script-land Convert returns the null pointer to signal failure.
  *   if tfst == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst)
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3351, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed_2, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3351, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3372, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Conversion_to_r_failed_2, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3372, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = NULL;
+    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
+      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+      if (likely(__pyx_t_8)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_8);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
+        __Pyx_DECREF_SET(__pyx_t_7, function);
       }
     }
-    if (!__pyx_t_7) {
-      __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_fst_type); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3351, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_5);
+    if (!__pyx_t_8) {
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_fst_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3372, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_6);
     } else {
       #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_6)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_fst_type};
-        __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __Pyx_GOTREF(__pyx_t_5);
+      if (PyFunction_Check(__pyx_t_7)) {
+        PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_fst_type};
+        __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_GOTREF(__pyx_t_6);
       } else
       #endif
       #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_v_fst_type};
-        __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-        __Pyx_GOTREF(__pyx_t_5);
+      if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
+        PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_fst_type};
+        __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __Pyx_GOTREF(__pyx_t_6);
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_8);
-        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
         __Pyx_INCREF(__pyx_v_fst_type);
         __Pyx_GIVEREF(__pyx_v_fst_type);
-        PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_v_fst_type);
-        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_5);
-        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_fst_type);
+        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
     }
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_7);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
       }
     }
-    if (!__pyx_t_6) {
-      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3351, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __Pyx_GOTREF(__pyx_t_3);
+    if (!__pyx_t_7) {
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3372, __pyx_L1_error)
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
-      if (PyFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-        __Pyx_GOTREF(__pyx_t_3);
-        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (PyFunction_Check(__pyx_t_5)) {
+        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       #if CYTHON_FAST_PYCCALL
-      if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
-        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
-        __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-        __Pyx_GOTREF(__pyx_t_3);
-        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
+        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_8);
-        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-        __Pyx_GIVEREF(__pyx_t_5);
-        PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
-        __pyx_t_5 = 0;
-        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3351, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_3);
-        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
+        __Pyx_GIVEREF(__pyx_t_6);
+        PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
+        __pyx_t_6 = 0;
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3372, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
     }
+    __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_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3351, __pyx_L1_error)
+    __PYX_ERR(0, 3372, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3350
- *   tfst = fst.Convert(deref(ifst._fst), tostring(fst_type))
+    /* "pywrapfst.pyx":3371
+ *   cdef FstClass_ptr tfst = fst.Convert(deref(ifst._fst), fst_type_string)
  *   # Script-land Convert returns the null pointer to signal failure.
  *   if tfst == NULL:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
@@ -36011,7 +35656,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":3352
+  /* "pywrapfst.pyx":3373
  *   if tfst == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
  *   return _init_XFst(tfst)             # <<<<<<<<<<<<<<
@@ -36019,28 +35664,28 @@ 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)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3352, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
-  __pyx_t_3 = 0;
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3373, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_4);
+  __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3330
+  /* "pywrapfst.pyx":3351
  * 
  * 
- * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef _Fst convert(_Fst ifst, fst_type=None):             # <<<<<<<<<<<<<<
  *   """
- *   convert(ifst, fst_type="")
+ *   convert(ifst, fst_type=None)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
   __Pyx_AddTraceback("pywrapfst.convert", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -36051,7 +35696,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_17convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_16convert[] = "\n  convert(ifst, fst_type=\"\")\n\n  Constructively converts an FST to a new internal representation.\n\n  Args:\n    ifst: The input FST.\n    fst_type: A string indicating the FST type to convert to, or None if\n      no conversion is desired.\n\n  Returns:\n    An equivalent Fst converted to the desired FST type.\n\n  Raises:\n    FstOpError: Conversion failed.\n  ";
+static char __pyx_doc_9pywrapfst_16convert[] = "\n  convert(ifst, fst_type=None)\n\n  Constructively converts an FST to a new internal representation.\n\n  Args:\n    ifst: The input FST.\n    fst_type: A string indicating the FST type to convert to, or None if\n        no conversion is desired.\n\n  Returns:\n    An equivalent Fst converted to the desired FST type.\n\n  Raises:\n    FstOpError: Conversion failed.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_17convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_fst_type = 0;
@@ -36061,7 +35706,7 @@ static PyObject *__pyx_pw_9pywrapfst_17convert(PyObject *__pyx_self, PyObject *_
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_fst_type,0};
     PyObject* values[2] = {0,0};
-    values[1] = ((PyObject *)__pyx_kp_b_);
+    values[1] = ((PyObject *)Py_None);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -36083,7 +35728,7 @@ static PyObject *__pyx_pw_9pywrapfst_17convert(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, 3330, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3351, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36098,13 +35743,13 @@ static PyObject *__pyx_pw_9pywrapfst_17convert(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, 3330, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3351, __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, 3330, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3351, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_16convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
@@ -36125,7 +35770,7 @@ static PyObject *__pyx_pf_9pywrapfst_16convert(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, 3330, __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, 3351, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36142,7 +35787,7 @@ static PyObject *__pyx_pf_9pywrapfst_16convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3355
+/* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36152,12 +35797,12 @@ static PyObject *__pyx_pf_9pywrapfst_16convert(CYTHON_UNUSED PyObject *__pyx_sel
 
 static PyObject *__pyx_pw_9pywrapfst_19determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__36;
+  float __pyx_v_delta = __pyx_k__40;
   PyObject *__pyx_v_det_type = ((PyObject *)__pyx_n_b_functional);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__37;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__41;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3360
+  /* "pywrapfst.pyx":3381
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36166,7 +35811,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3361
+  /* "pywrapfst.pyx":3382
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36211,7 +35856,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
   }
 
-  /* "pywrapfst.pyx":3396
+  /* "pywrapfst.pyx":3417
  *   See also: `disambiguate`, `rmepsilon`.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -36220,11 +35865,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3396, __pyx_L1_error)
+    __PYX_ERR(0, 3417, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3398
+  /* "pywrapfst.pyx":3419
  *   cdef VectorFstClass_ptr tfst = 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(),             # <<<<<<<<<<<<<<
@@ -36233,29 +35878,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 '%s'", "weight_type");
-    __PYX_ERR(0, 3398, __pyx_L1_error)
+    __PYX_ERR(0, 3419, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3399
+  /* "pywrapfst.pyx":3420
  *   # 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, 3398, __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, 3419, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3401
+  /* "pywrapfst.pyx":3422
  *                                                      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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3401, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3422, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3402
+  /* "pywrapfst.pyx":3423
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),
  *                                 addr(determinize_type_enum)):             # <<<<<<<<<<<<<<
@@ -36264,7 +35909,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":3401
+  /* "pywrapfst.pyx":3422
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36273,16 +35918,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3403
+    /* "pywrapfst.pyx":3424
  *   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_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3403, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3424, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3403, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3424, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -36295,13 +35940,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
       }
     }
     if (!__pyx_t_8) {
-      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_det_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3403, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_det_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3424, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_7)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_det_type};
-        __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_6);
       } else
@@ -36309,19 +35954,19 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_det_type};
-        __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_6);
       } else
       #endif
       {
-        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
         __Pyx_INCREF(__pyx_v_det_type);
         __Pyx_GIVEREF(__pyx_v_det_type);
         PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_det_type);
-        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
@@ -36338,14 +35983,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3403, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3424, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -36354,20 +35999,20 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3403, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3424, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
@@ -36375,9 +36020,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     __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, 3403, __pyx_L1_error)
+    __PYX_ERR(0, 3424, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3401
+    /* "pywrapfst.pyx":3422
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -36386,7 +36031,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   }
 
-  /* "pywrapfst.pyx":3405
+  /* "pywrapfst.pyx":3426
  *     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,             # <<<<<<<<<<<<<<
@@ -36395,7 +36040,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":3408
+  /* "pywrapfst.pyx":3429
  *                                         determinize_type_enum,
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -36404,11 +36049,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 '%s'", "_fst");
-    __PYX_ERR(0, 3408, __pyx_L1_error)
+    __PYX_ERR(0, 3429, __pyx_L1_error)
   }
   fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3409
+  /* "pywrapfst.pyx":3430
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -36416,13 +36061,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)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3409, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3430, __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":3355
+  /* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36465,7 +36110,7 @@ static PyObject *__pyx_pw_9pywrapfst_19determinize(PyObject *__pyx_self, PyObjec
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_functional);
 
-    /* "pywrapfst.pyx":3360
+    /* "pywrapfst.pyx":3381
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None,             # <<<<<<<<<<<<<<
@@ -36524,7 +36169,7 @@ static PyObject *__pyx_pw_9pywrapfst_19determinize(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, 3355, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3376, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36541,27 +36186,27 @@ static PyObject *__pyx_pw_9pywrapfst_19determinize(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, 3356, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3377, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__36;
+      __pyx_v_delta = __pyx_k__40;
     }
     __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, 3358, __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, 3379, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__37;
+      __pyx_v_nstate = __pyx_k__41;
     }
     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, 3359, __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, 3380, __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, 3361, __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, 3382, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3361
+      /* "pywrapfst.pyx":3382
  *                               int64 subsequential_label=0,
  *                               weight=None,
  *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -36573,16 +36218,16 @@ static PyObject *__pyx_pw_9pywrapfst_19determinize(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, 3355, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3376, __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, 3355, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3376, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_18determinize(__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":3355
+  /* "pywrapfst.pyx":3376
  * 
  * 
  * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36613,7 +36258,7 @@ static PyObject *__pyx_pf_9pywrapfst_18determinize(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, 3355, __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, 3376, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36630,7 +36275,7 @@ static PyObject *__pyx_pf_9pywrapfst_18determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3412
+/* "pywrapfst.pyx":3433
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36642,7 +36287,7 @@ static PyObject *__pyx_pw_9pywrapfst_21difference(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":3415
+  /* "pywrapfst.pyx":3436
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -36667,8 +36312,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
     }
   }
 
-  /* "pywrapfst.pyx":3438
- *     An FST representing the difference of the two input FSTs.
+  /* "pywrapfst.pyx":3459
+ *     An FST representing the difference of the FSTs.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ComposeOptions] opts
@@ -36676,30 +36321,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3438, __pyx_L1_error)
+    __PYX_ERR(0, 3459, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0));
 
-  /* "pywrapfst.pyx":3441
+  /* "pywrapfst.pyx":3462
  *   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, deref(opts))
  *   return _init_MutableFst(tfst)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3441, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3462, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3440
+  /* "pywrapfst.pyx":3461
  *   cdef VectorFstClass_ptr tfst = 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, deref(opts))
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3440, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3461, __pyx_L1_error)
   __pyx_v_opts.reset(new fst::script::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3442
+  /* "pywrapfst.pyx":3463
  *   opts.reset(new fst.ComposeOptions(connect, _get_compose_filter(
  *       tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -36708,15 +36353,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 '%s'", "_fst");
-    __PYX_ERR(0, 3442, __pyx_L1_error)
+    __PYX_ERR(0, 3463, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3442, __pyx_L1_error)
+    __PYX_ERR(0, 3463, __pyx_L1_error)
   }
   fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3443
+  /* "pywrapfst.pyx":3464
  *       tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -36724,13 +36369,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)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3443, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3464, __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":3412
+  /* "pywrapfst.pyx":3433
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36751,7 +36396,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_21difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_20difference[] = "\n  difference(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively computes the difference of two FSTs.\n\n  This operation computes the difference between two FSAs. Only strings that are\n  in the first automaton but not in second are retained in the result. The first\n  argument must be an acceptor; the second argument must be an unweighted,\n  epsilon-free, deterministic acceptor. The output labels of the first\n  transducer or the input labels of the second transducer must be sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should the output FST be trimmed?\n\n  Returns:\n    An FST representing the difference of the two input FSTs.\n  ";
+static char __pyx_doc_9pywrapfst_20difference[] = "\n  difference(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively computes the difference of two FSTs.\n\n  This operation computes the difference between two FSAs. Only strings that are\n  in the first automaton but not in second are retained in the result. The first\n  argument must be an acceptor; the second argument must be an unweighted,\n  epsilon-free, deterministic acceptor. The output labels of the first\n  transducer or the input labels of the second transducer must be sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should the output FST be trimmed?\n\n  Returns:\n    An FST representing the difference of the FSTs.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_21difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2 = 0;
@@ -36783,7 +36428,7 @@ static PyObject *__pyx_pw_9pywrapfst_21difference(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3412, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3433, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -36797,7 +36442,7 @@ static PyObject *__pyx_pw_9pywrapfst_21difference(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, 3412, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3433, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -36813,10 +36458,10 @@ static PyObject *__pyx_pw_9pywrapfst_21difference(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, 3415, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3436, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3415
+      /* "pywrapfst.pyx":3436
  *                              _Fst ifst2,
  *                              compose_filter=b"auto",
  *                              bool connect=True):             # <<<<<<<<<<<<<<
@@ -36828,17 +36473,17 @@ static PyObject *__pyx_pw_9pywrapfst_21difference(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, 3412, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3433, __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, 3412, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3413, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3433, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3434, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_20difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3412
+  /* "pywrapfst.pyx":3433
  * 
  * 
  * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -36865,7 +36510,7 @@ static PyObject *__pyx_pf_9pywrapfst_20difference(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, 3412, __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, 3433, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36882,7 +36527,7 @@ static PyObject *__pyx_pf_9pywrapfst_20difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3446
+/* "pywrapfst.pyx":3467
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -36892,11 +36537,11 @@ static PyObject *__pyx_pf_9pywrapfst_20difference(CYTHON_UNUSED PyObject *__pyx_
 
 static PyObject *__pyx_pw_9pywrapfst_23disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__38;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__39;
+  float __pyx_v_delta = __pyx_k__42;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__43;
   __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
 
-  /* "pywrapfst.pyx":3450
+  /* "pywrapfst.pyx":3471
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -36927,7 +36572,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
     }
   }
 
-  /* "pywrapfst.pyx":3476
+  /* "pywrapfst.pyx":3497
  *   See also: `determinize`, `rmepsilon`.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -36936,11 +36581,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3476, __pyx_L1_error)
+    __PYX_ERR(0, 3497, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3478
+  /* "pywrapfst.pyx":3499
  *   cdef VectorFstClass_ptr tfst = 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(),             # <<<<<<<<<<<<<<
@@ -36949,20 +36594,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 '%s'", "weight_type");
-    __PYX_ERR(0, 3478, __pyx_L1_error)
+    __PYX_ERR(0, 3499, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3479
+  /* "pywrapfst.pyx":3500
  *   # 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, 3478, __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, 3499, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3481
+  /* "pywrapfst.pyx":3502
  *                                                      weight)
  *   cdef unique_ptr[fst.DisambiguateOptions] opts
  *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,             # <<<<<<<<<<<<<<
@@ -36971,7 +36616,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":3483
+  /* "pywrapfst.pyx":3504
  *   opts.reset(new fst.DisambiguateOptions(delta, wc, nstate,
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -36980,11 +36625,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 '%s'", "_fst");
-    __PYX_ERR(0, 3483, __pyx_L1_error)
+    __PYX_ERR(0, 3504, __pyx_L1_error)
   }
   fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3484
+  /* "pywrapfst.pyx":3505
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -36992,13 +36637,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)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3484, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3505, __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":3446
+  /* "pywrapfst.pyx":3467
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37033,7 +36678,7 @@ static PyObject *__pyx_pw_9pywrapfst_23disambiguate(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":3450
+    /* "pywrapfst.pyx":3471
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -37080,7 +36725,7 @@ static PyObject *__pyx_pw_9pywrapfst_23disambiguate(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, 3446, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3467, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37095,17 +36740,17 @@ static PyObject *__pyx_pw_9pywrapfst_23disambiguate(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, 3447, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3468, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__38;
+      __pyx_v_delta = __pyx_k__42;
     }
     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, 3448, __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, 3469, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__39;
+      __pyx_v_nstate = __pyx_k__43;
     }
     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, 3449, __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, 3470, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
     }
@@ -37113,16 +36758,16 @@ static PyObject *__pyx_pw_9pywrapfst_23disambiguate(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, 3446, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3467, __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, 3446, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3467, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_22disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3446
+  /* "pywrapfst.pyx":3467
  * 
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -37151,7 +36796,7 @@ static PyObject *__pyx_pf_9pywrapfst_22disambiguate(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, 3446, __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, 3467, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37168,7 +36813,7 @@ static PyObject *__pyx_pf_9pywrapfst_22disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3487
+/* "pywrapfst.pyx":3508
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37191,7 +36836,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     }
   }
 
-  /* "pywrapfst.pyx":3509
+  /* "pywrapfst.pyx":3530
  *   See also: `rmepsilon`.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -37200,11 +36845,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3509, __pyx_L1_error)
+    __PYX_ERR(0, 3530, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3510
+  /* "pywrapfst.pyx":3531
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.EpsNormalize(deref(ifst._fst), tfst, fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37213,10 +36858,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 '%s'", "_fst");
-    __PYX_ERR(0, 3510, __pyx_L1_error)
+    __PYX_ERR(0, 3531, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3511
+  /* "pywrapfst.pyx":3532
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.EpsNormalize(deref(ifst._fst), tfst, fst.EPS_NORM_OUTPUT if
  *                                            eps_norm_output else             # <<<<<<<<<<<<<<
@@ -37225,7 +36870,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if ((__pyx_v_eps_norm_output != 0)) {
 
-    /* "pywrapfst.pyx":3510
+    /* "pywrapfst.pyx":3531
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.EpsNormalize(deref(ifst._fst), tfst, fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37235,7 +36880,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     __pyx_t_1 = fst::EPS_NORM_OUTPUT;
   } else {
 
-    /* "pywrapfst.pyx":3512
+    /* "pywrapfst.pyx":3533
  *   fst.EpsNormalize(deref(ifst._fst), tfst, fst.EPS_NORM_OUTPUT if
  *                                            eps_norm_output else
  *                                            fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
@@ -37245,7 +36890,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3510
+  /* "pywrapfst.pyx":3531
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.EpsNormalize(deref(ifst._fst), tfst, fst.EPS_NORM_OUTPUT if             # <<<<<<<<<<<<<<
@@ -37254,7 +36899,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_t_1);
 
-  /* "pywrapfst.pyx":3513
+  /* "pywrapfst.pyx":3534
  *                                            eps_norm_output else
  *                                            fst.EPS_NORM_INPUT)
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -37262,13 +36907,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)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3513, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3534, __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":3487
+  /* "pywrapfst.pyx":3508
  * 
  * 
  * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -37320,7 +36965,7 @@ static PyObject *__pyx_pw_9pywrapfst_25epsnormalize(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, 3487, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3508, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37332,20 +36977,20 @@ static PyObject *__pyx_pw_9pywrapfst_25epsnormalize(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, 3487, __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, 3508, __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, 3487, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3508, __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, 3487, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3508, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_24epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
@@ -37366,7 +37011,7 @@ static PyObject *__pyx_pf_9pywrapfst_24epsnormalize(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, 3487, __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, 3508, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37383,7 +37028,7 @@ static PyObject *__pyx_pf_9pywrapfst_24epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3516
+/* "pywrapfst.pyx":3537
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37393,7 +37038,7 @@ static PyObject *__pyx_pf_9pywrapfst_24epsnormalize(CYTHON_UNUSED PyObject *__py
 
 static PyObject *__pyx_pw_9pywrapfst_27equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_equal(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_equal *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__40;
+  float __pyx_v_delta = __pyx_k__44;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equal", 0);
@@ -37403,7 +37048,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
     }
   }
 
-  /* "pywrapfst.pyx":3536
+  /* "pywrapfst.pyx":3557
  *   See also: `equivalent`, `isomorphic`, `randequivalent`.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -37412,16 +37057,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 '%s'", "_fst");
-    __PYX_ERR(0, 3536, __pyx_L1_error)
+    __PYX_ERR(0, 3557, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3536, __pyx_L1_error)
+    __PYX_ERR(0, 3557, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3516
+  /* "pywrapfst.pyx":3537
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -37440,7 +37085,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_27equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_26equal[] = "\n  equal(ifst1, ifst2, delta=0.0009765625)\n\n  Are two FSTs equal?\n\n  This function tests whether two FSTs have the same states with the same\n  numbering and the same transitions with the same labels and weights in the\n  same order.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n\n  See also: `equivalent`, `isomorphic`, `randequivalent`.\n  ";
+static char __pyx_doc_9pywrapfst_26equal[] = "\n  equal(ifst1, ifst2, delta=0.0009765625)\n\n  Are two FSTs equal?\n\n  This function tests whether two FSTs have the same states with the same\n  numbering and the same transitions with the same labels and weights in the\n  same order.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the FSTs satisfy the above condition, else False.\n\n  See also: `equivalent`, `isomorphic`, `randequivalent`.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_27equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2 = 0;
@@ -37469,7 +37114,7 @@ static PyObject *__pyx_pw_9pywrapfst_27equal(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3516, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3537, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -37478,7 +37123,7 @@ static PyObject *__pyx_pw_9pywrapfst_27equal(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, 3516, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3537, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37492,21 +37137,21 @@ static PyObject *__pyx_pw_9pywrapfst_27equal(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, 3516, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3537, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__40;
+      __pyx_v_delta = __pyx_k__44;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3516, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3537, __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, 3516, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3516, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3537, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3537, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_26equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -37529,7 +37174,7 @@ static PyObject *__pyx_pf_9pywrapfst_26equal(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, 3516, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3537, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -37546,7 +37191,7 @@ static PyObject *__pyx_pf_9pywrapfst_26equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3539
+/* "pywrapfst.pyx":3560
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -37556,7 +37201,7 @@ static PyObject *__pyx_pf_9pywrapfst_26equal(CYTHON_UNUSED PyObject *__pyx_self,
 
 static PyObject *__pyx_pw_9pywrapfst_29equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_equivalent(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_equivalent *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__41;
+  float __pyx_v_delta = __pyx_k__45;
   bool __pyx_v_error;
   bool __pyx_v_result;
   bool __pyx_r;
@@ -37571,7 +37216,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3563
+  /* "pywrapfst.pyx":3584
  *   """
  *   cdef bool error
  *   cdef bool result = fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta,             # <<<<<<<<<<<<<<
@@ -37580,14 +37225,14 @@ 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 '%s'", "_fst");
-    __PYX_ERR(0, 3563, __pyx_L1_error)
+    __PYX_ERR(0, 3584, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3563, __pyx_L1_error)
+    __PYX_ERR(0, 3584, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3564
+  /* "pywrapfst.pyx":3585
  *   cdef bool error
  *   cdef bool result = fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta,
  *                                     addr(error))             # <<<<<<<<<<<<<<
@@ -37596,7 +37241,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   __pyx_v_result = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta, (&__pyx_v_error));
 
-  /* "pywrapfst.pyx":3565
+  /* "pywrapfst.pyx":3586
  *   cdef bool result = fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta,
  *                                     addr(error))
  *   if error:             # <<<<<<<<<<<<<<
@@ -37606,23 +37251,23 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
   __pyx_t_1 = (__pyx_v_error != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":3566
+    /* "pywrapfst.pyx":3587
  *                                     addr(error))
  *   if error:
  *     raise FstOpError("Equivalence test encountered error")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3566, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3587, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3566, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__46, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3587, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3566, __pyx_L1_error)
+    __PYX_ERR(0, 3587, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3565
+    /* "pywrapfst.pyx":3586
  *   cdef bool result = fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta,
  *                                     addr(error))
  *   if error:             # <<<<<<<<<<<<<<
@@ -37631,7 +37276,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   }
 
-  /* "pywrapfst.pyx":3567
+  /* "pywrapfst.pyx":3588
  *   if error:
  *     raise FstOpError("Equivalence test encountered error")
  *   return result             # <<<<<<<<<<<<<<
@@ -37641,7 +37286,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3539
+  /* "pywrapfst.pyx":3560
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
@@ -37662,7 +37307,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_29equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_28equivalent[] = "\n  equivalent(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors equivalent?\n\n  This operation tests whether two epsilon-free deterministic weighted\n  acceptors are equivalent, that is if they accept the same strings with the\n  same weights.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n\n  Raises:\n    FstOpError: Equivalence test encountered error.\n\n  See also: `equal`, `isomorphic`, `randequivalent`.\n  ";
+static char __pyx_doc_9pywrapfst_28equivalent[] = "\n  equivalent(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors equivalent?\n\n  This operation tests whether two epsilon-free deterministic weighted\n  acceptors are equivalent, that is if they accept the same strings with the\n  same weights.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the FSTs satisfy the above condition, else False.\n\n  Raises:\n    FstOpError: Equivalence test encountered error.\n\n  See also: `equal`, `isomorphic`, `randequivalent`.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_29equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2 = 0;
@@ -37691,7 +37336,7 @@ static PyObject *__pyx_pw_9pywrapfst_29equivalent(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3539, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3560, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -37700,7 +37345,7 @@ static PyObject *__pyx_pw_9pywrapfst_29equivalent(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, 3539, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3560, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37714,21 +37359,21 @@ static PyObject *__pyx_pw_9pywrapfst_29equivalent(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, 3539, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3560, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__41;
+      __pyx_v_delta = __pyx_k__45;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3539, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3560, __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, 3539, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3539, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3560, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3560, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_28equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -37750,8 +37395,8 @@ static PyObject *__pyx_pf_9pywrapfst_28equivalent(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(PyErr_Occurred())) __PYX_ERR(0, 3539, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3539, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3560, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3560, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -37768,7 +37413,7 @@ static PyObject *__pyx_pf_9pywrapfst_28equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3570
+/* "pywrapfst.pyx":3591
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37780,7 +37425,7 @@ static PyObject *__pyx_pw_9pywrapfst_31intersect(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":3573
+  /* "pywrapfst.pyx":3594
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -37805,8 +37450,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
     }
   }
 
-  /* "pywrapfst.pyx":3594
- *     An equivalent epsilon-normalized FST.
+  /* "pywrapfst.pyx":3615
+ *     An intersected FST.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.ComposeOptions] opts
@@ -37814,21 +37459,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3594, __pyx_L1_error)
+    __PYX_ERR(0, 3615, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0));
 
-  /* "pywrapfst.pyx":3597
+  /* "pywrapfst.pyx":3618
  *   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, deref(opts))
  *   return _init_MutableFst(tfst)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3597, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3597, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3618, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3618, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3596
+  /* "pywrapfst.pyx":3617
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(connect,             # <<<<<<<<<<<<<<
@@ -37837,7 +37482,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   __pyx_v_opts.reset(new fst::script::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3598
+  /* "pywrapfst.pyx":3619
  *   opts.reset(new fst.ComposeOptions(connect,
  *         _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -37846,15 +37491,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 '%s'", "_fst");
-    __PYX_ERR(0, 3598, __pyx_L1_error)
+    __PYX_ERR(0, 3619, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3598, __pyx_L1_error)
+    __PYX_ERR(0, 3619, __pyx_L1_error)
   }
   fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3599
+  /* "pywrapfst.pyx":3620
  *         _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -37862,13 +37507,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)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3599, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3620, __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":3570
+  /* "pywrapfst.pyx":3591
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -37889,7 +37534,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_31intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_30intersect[] = "\n  intersect(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively intersects two FSTs.\n\n  This operation computes the intersection (Hadamard product) of two FSTs.\n  Only strings that are in both automata are retained in the result. The two\n  arguments must be acceptors. One of the arguments must be label-sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An equivalent epsilon-normalized FST.\n  ";
+static char __pyx_doc_9pywrapfst_30intersect[] = "\n  intersect(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively intersects two FSTs.\n\n  This operation computes the intersection (Hadamard product) of two FSTs.\n  Only strings that are in both automata are retained in the result. The two\n  arguments must be acceptors. One of the arguments must be label-sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"null\", \"sequence\", \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An intersected FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_31intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2 = 0;
@@ -37921,7 +37566,7 @@ static PyObject *__pyx_pw_9pywrapfst_31intersect(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3570, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3591, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -37935,7 +37580,7 @@ static PyObject *__pyx_pw_9pywrapfst_31intersect(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, 3570, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3591, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37951,10 +37596,10 @@ static PyObject *__pyx_pw_9pywrapfst_31intersect(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, 3573, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3594, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3573
+      /* "pywrapfst.pyx":3594
  *                             _Fst ifst2,
  *                             compose_filter=b"auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
@@ -37966,17 +37611,17 @@ static PyObject *__pyx_pw_9pywrapfst_31intersect(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, 3570, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3591, __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, 3570, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3571, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3591, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3592, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_30intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3570
+  /* "pywrapfst.pyx":3591
  * 
  * 
  * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38003,7 +37648,7 @@ static PyObject *__pyx_pf_9pywrapfst_30intersect(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, 3570, __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, 3591, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38020,7 +37665,7 @@ static PyObject *__pyx_pf_9pywrapfst_30intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3602
+/* "pywrapfst.pyx":3623
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38030,7 +37675,7 @@ static PyObject *__pyx_pf_9pywrapfst_30intersect(CYTHON_UNUSED PyObject *__pyx_s
 
 static PyObject *__pyx_pw_9pywrapfst_33isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_isomorphic(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_isomorphic *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__43;
+  float __pyx_v_delta = __pyx_k__47;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("isomorphic", 0);
@@ -38040,7 +37685,7 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3625
+  /* "pywrapfst.pyx":3646
  *   See also: `equal`, `equivalent`, `randequivalent`.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -38049,16 +37694,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 '%s'", "_fst");
-    __PYX_ERR(0, 3625, __pyx_L1_error)
+    __PYX_ERR(0, 3646, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3625, __pyx_L1_error)
+    __PYX_ERR(0, 3646, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3602
+  /* "pywrapfst.pyx":3623
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -38106,7 +37751,7 @@ static PyObject *__pyx_pw_9pywrapfst_33isomorphic(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3602, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3623, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -38115,7 +37760,7 @@ static PyObject *__pyx_pw_9pywrapfst_33isomorphic(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, 3602, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3623, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38129,21 +37774,21 @@ static PyObject *__pyx_pw_9pywrapfst_33isomorphic(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, 3602, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3623, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__43;
+      __pyx_v_delta = __pyx_k__47;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3602, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3623, __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, 3602, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3602, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3623, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3623, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_32isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -38166,7 +37811,7 @@ static PyObject *__pyx_pf_9pywrapfst_32isomorphic(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, 3602, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3623, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38183,7 +37828,7 @@ static PyObject *__pyx_pf_9pywrapfst_32isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3628
+/* "pywrapfst.pyx":3649
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38193,10 +37838,10 @@ static PyObject *__pyx_pf_9pywrapfst_32isomorphic(CYTHON_UNUSED PyObject *__pyx_
 
 static PyObject *__pyx_pw_9pywrapfst_35prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__44;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__45;
+  float __pyx_v_delta = __pyx_k__48;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__49;
 
-  /* "pywrapfst.pyx":3631
+  /* "pywrapfst.pyx":3652
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38223,7 +37868,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
     }
   }
 
-  /* "pywrapfst.pyx":3654
+  /* "pywrapfst.pyx":3675
  *   See also: The destructive variant.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -38232,11 +37877,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3654, __pyx_L1_error)
+    __PYX_ERR(0, 3675, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3655
+  /* "pywrapfst.pyx":3676
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -38245,12 +37890,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 '%s'", "weight_type");
-    __PYX_ERR(0, 3655, __pyx_L1_error)
+    __PYX_ERR(0, 3676, __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, 3655, __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, 3676, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3656
+  /* "pywrapfst.pyx":3677
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst, wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -38259,11 +37904,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 '%s'", "_fst");
-    __PYX_ERR(0, 3656, __pyx_L1_error)
+    __PYX_ERR(0, 3677, __pyx_L1_error)
   }
   fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3657
+  /* "pywrapfst.pyx":3678
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   fst.Prune(deref(ifst._fst), tfst, wc, nstate, delta)
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -38271,13 +37916,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)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3657, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3678, __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":3628
+  /* "pywrapfst.pyx":3649
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38311,7 +37956,7 @@ static PyObject *__pyx_pw_9pywrapfst_35prune(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":3631
+    /* "pywrapfst.pyx":3652
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):             # <<<<<<<<<<<<<<
@@ -38352,7 +37997,7 @@ static PyObject *__pyx_pw_9pywrapfst_35prune(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, 3628, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3649, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38366,29 +38011,29 @@ static PyObject *__pyx_pw_9pywrapfst_35prune(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, 3629, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3650, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__44;
+      __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, 3630, __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, 3651, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__45;
+      __pyx_v_nstate = __pyx_k__49;
     }
     __pyx_v_weight = values[3];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3628, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3649, __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, 3628, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3649, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_34prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3628
+  /* "pywrapfst.pyx":3649
  * 
  * 
  * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38416,7 +38061,7 @@ static PyObject *__pyx_pf_9pywrapfst_34prune(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, 3628, __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, 3649, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38433,7 +38078,7 @@ static PyObject *__pyx_pf_9pywrapfst_34prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3660
+/* "pywrapfst.pyx":3681
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38443,9 +38088,9 @@ static PyObject *__pyx_pf_9pywrapfst_34prune(CYTHON_UNUSED PyObject *__pyx_self,
 
 static PyObject *__pyx_pw_9pywrapfst_37push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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__46;
+  float __pyx_v_delta = __pyx_k__50;
 
-  /* "pywrapfst.pyx":3662
+  /* "pywrapfst.pyx":3683
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -38454,7 +38099,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3663
+  /* "pywrapfst.pyx":3684
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -38463,7 +38108,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3664
+  /* "pywrapfst.pyx":3685
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -38472,7 +38117,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3665
+  /* "pywrapfst.pyx":3686
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -38481,7 +38126,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3666
+  /* "pywrapfst.pyx":3687
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -38516,7 +38161,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3705
+  /* "pywrapfst.pyx":3726
  *   """
  *   # This is copied, almost verbatim, from nlp/fst/bin/fstpush.cc.
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -38525,11 +38170,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3705, __pyx_L1_error)
+    __PYX_ERR(0, 3726, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3706
+  /* "pywrapfst.pyx":3727
  *   # This is copied, almost verbatim, from nlp/fst/bin/fstpush.cc.
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,             # <<<<<<<<<<<<<<
@@ -38538,7 +38183,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":3708
+  /* "pywrapfst.pyx":3729
  *   cdef uint32 flags = fst.GetPushFlags(push_weights, push_labels,
  *                                        remove_common_affix, remove_total_weight)
  *   fst.Push(deref(ifst._fst), tfst, flags, fst.GetReweightType(to_final), delta)             # <<<<<<<<<<<<<<
@@ -38547,11 +38192,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 '%s'", "_fst");
-    __PYX_ERR(0, 3708, __pyx_L1_error)
+    __PYX_ERR(0, 3729, __pyx_L1_error)
   }
   fst::script::Push((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_flags, fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3709
+  /* "pywrapfst.pyx":3730
  *                                        remove_common_affix, remove_total_weight)
  *   fst.Push(deref(ifst._fst), tfst, flags, fst.GetReweightType(to_final), delta)
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -38559,13 +38204,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)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3709, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3730, __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":3660
+  /* "pywrapfst.pyx":3681
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38652,7 +38297,7 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3660, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3681, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38669,15 +38314,15 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3661, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3682, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__46;
+      __pyx_v_delta = __pyx_k__50;
     }
     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, 3662, __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, 3683, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3662
+      /* "pywrapfst.pyx":3683
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -38687,10 +38332,10 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3663, __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, 3684, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3663
+      /* "pywrapfst.pyx":3684
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  *                        bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -38700,10 +38345,10 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3664, __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, 3685, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3664
+      /* "pywrapfst.pyx":3685
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -38713,10 +38358,10 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3665, __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, 3686, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3665
+      /* "pywrapfst.pyx":3686
  *                        bool push_labels=False,
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -38726,10 +38371,10 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3666, __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, 3687, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3666
+      /* "pywrapfst.pyx":3687
  *                        bool remove_common_affix=False,
  *                        bool remove_total_weight=False,
  *                        bool to_final=False):             # <<<<<<<<<<<<<<
@@ -38741,16 +38386,16 @@ static PyObject *__pyx_pw_9pywrapfst_37push(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, 3660, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3681, __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, 3660, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3681, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_36push(__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":3660
+  /* "pywrapfst.pyx":3681
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -38781,7 +38426,7 @@ static PyObject *__pyx_pf_9pywrapfst_36push(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, 3660, __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, 3681, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38798,7 +38443,7 @@ static PyObject *__pyx_pf_9pywrapfst_36push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3712
+/* "pywrapfst.pyx":3733
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -38809,10 +38454,10 @@ static PyObject *__pyx_pf_9pywrapfst_36push(CYTHON_UNUSED PyObject *__pyx_self,
 static PyObject *__pyx_pw_9pywrapfst_39randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_randequivalent(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_randequivalent *__pyx_optional_args) {
   __pyx_t_10basictypes_int32 __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
-  float __pyx_v_delta = __pyx_k__47;
+  float __pyx_v_delta = __pyx_k__51;
   time_t __pyx_v_seed = ((time_t)0);
   PyObject *__pyx_v_select = ((PyObject *)__pyx_n_b_uniform);
-  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__48;
+  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__52;
   enum fst::script::RandArcSelection __pyx_v_ras;
   std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v_opts;
   bool __pyx_v_error;
@@ -38843,18 +38488,18 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
     }
   }
 
-  /* "pywrapfst.pyx":3750
+  /* "pywrapfst.pyx":3771
  *   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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3750, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3750, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3771, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3771, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3753
+  /* "pywrapfst.pyx":3774
  *   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,             # <<<<<<<<<<<<<<
@@ -38863,7 +38508,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":3755
+  /* "pywrapfst.pyx":3776
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
  *                                                           1, False, False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -38873,7 +38518,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":3756
+    /* "pywrapfst.pyx":3777
  *                                                           1, False, False))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -38882,7 +38527,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3755
+    /* "pywrapfst.pyx":3776
  *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras, max_length,
  *                                                           1, False, False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -38891,7 +38536,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   }
 
-  /* "pywrapfst.pyx":3758
+  /* "pywrapfst.pyx":3779
  *     seed = time(NULL) + getpid()
  *   cdef bool error
  *   cdef bool result = fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst),             # <<<<<<<<<<<<<<
@@ -38900,14 +38545,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 '%s'", "_fst");
-    __PYX_ERR(0, 3758, __pyx_L1_error)
+    __PYX_ERR(0, 3779, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3758, __pyx_L1_error)
+    __PYX_ERR(0, 3779, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3760
+  /* "pywrapfst.pyx":3781
  *   cdef bool result = fst.RandEquivalent(deref(ifst1._fst), deref(ifst2._fst),
  *                                         npath, delta, seed, deref(opts),
  *                                         addr(error))             # <<<<<<<<<<<<<<
@@ -38916,7 +38561,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   __pyx_v_result = fst::script::RandEquivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, (*__pyx_v_opts), (&__pyx_v_error));
 
-  /* "pywrapfst.pyx":3761
+  /* "pywrapfst.pyx":3782
  *                                         npath, delta, seed, deref(opts),
  *                                         addr(error))
  *   if error:             # <<<<<<<<<<<<<<
@@ -38926,23 +38571,23 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
   __pyx_t_3 = (__pyx_v_error != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3762
+    /* "pywrapfst.pyx":3783
  *                                         addr(error))
  *   if error:
  *     raise FstOpError("Random equivalence test encountered error")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3762, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3783, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3762, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3783, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_5, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __PYX_ERR(0, 3762, __pyx_L1_error)
+    __PYX_ERR(0, 3783, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3761
+    /* "pywrapfst.pyx":3782
  *                                         npath, delta, seed, deref(opts),
  *                                         addr(error))
  *   if error:             # <<<<<<<<<<<<<<
@@ -38951,7 +38596,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   }
 
-  /* "pywrapfst.pyx":3763
+  /* "pywrapfst.pyx":3784
  *   if error:
  *     raise FstOpError("Random equivalence test encountered error")
  *   return result             # <<<<<<<<<<<<<<
@@ -38961,7 +38606,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3712
+  /* "pywrapfst.pyx":3733
  * 
  * 
  * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
@@ -39020,7 +38665,7 @@ static PyObject *__pyx_pw_9pywrapfst_39randequivalent(PyObject *__pyx_self, PyOb
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3712, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3733, __pyx_L3_error)
         }
         case  2:
         if (kw_args > 0) {
@@ -39049,7 +38694,7 @@ static PyObject *__pyx_pw_9pywrapfst_39randequivalent(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, 3712, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3733, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39067,37 +38712,37 @@ static PyObject *__pyx_pw_9pywrapfst_39randequivalent(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, 3714, __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, 3735, __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, 3715, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3736, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__47;
+      __pyx_v_delta = __pyx_k__51;
     }
     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, 3716, __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, 3737, __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, 3718, __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, 3739, __pyx_L3_error)
     } else {
-      __pyx_v_max_length = __pyx_k__48;
+      __pyx_v_max_length = __pyx_k__52;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3712, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3733, __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, 3712, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3713, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst__Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3733, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3734, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_38randequivalent(__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 */
@@ -39123,8 +38768,8 @@ static PyObject *__pyx_pf_9pywrapfst_38randequivalent(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(PyErr_Occurred())) __PYX_ERR(0, 3712, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3712, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3733, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3733, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39141,7 +38786,7 @@ static PyObject *__pyx_pf_9pywrapfst_38randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3766
+/* "pywrapfst.pyx":3787
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39154,9 +38799,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
   __pyx_t_10basictypes_int32 __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
   time_t __pyx_v_seed = ((time_t)0);
   PyObject *__pyx_v_select = ((PyObject *)__pyx_n_b_uniform);
-  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__50;
+  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__54;
 
-  /* "pywrapfst.pyx":3771
+  /* "pywrapfst.pyx":3792
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39165,7 +38810,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3772
+  /* "pywrapfst.pyx":3793
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39204,18 +38849,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
     }
   }
 
-  /* "pywrapfst.pyx":3804
+  /* "pywrapfst.pyx":3825
  *   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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3804, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3804, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3825, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3825, __pyx_L1_error)
   __pyx_v_ras = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3806
+  /* "pywrapfst.pyx":3827
  *   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,             # <<<<<<<<<<<<<<
@@ -39224,7 +38869,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":3809
+  /* "pywrapfst.pyx":3830
  *                                                           npath, weighted,
  *                                                           remove_total_weight))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -39233,11 +38878,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3809, __pyx_L1_error)
+    __PYX_ERR(0, 3830, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3810
+  /* "pywrapfst.pyx":3831
  *                                                           remove_total_weight))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39247,7 +38892,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":3811
+    /* "pywrapfst.pyx":3832
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -39256,7 +38901,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3810
+    /* "pywrapfst.pyx":3831
  *                                                           remove_total_weight))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -39265,7 +38910,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   }
 
-  /* "pywrapfst.pyx":3812
+  /* "pywrapfst.pyx":3833
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst, seed, deref(opts))             # <<<<<<<<<<<<<<
@@ -39274,11 +38919,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 '%s'", "_fst");
-    __PYX_ERR(0, 3812, __pyx_L1_error)
+    __PYX_ERR(0, 3833, __pyx_L1_error)
   }
   fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_seed, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3813
+  /* "pywrapfst.pyx":3834
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst, seed, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -39286,13 +38931,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)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3813, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3834, __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":3766
+  /* "pywrapfst.pyx":3787
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39313,7 +38958,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_41randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_40randgen[] = "\n  randgen(ifst, npath=1, seed=0, select=\"uniform\", max_length=2147483647,\n          weight=False, remove_total_weight=False)\n\n  Randomly generate successful paths in an FST.\n\n  This operation randomly generates a set of successful paths in the input FST.\n  This relies on a mechanism for selecting arcs, specified using the `select`\n  argument. The default selector, \"uniform\", randomly selects a transition\n  using a uniform distribution. The \"log_prob\" selector randomly selects a\n  transition w.r.t. the weights treated as negative log probabilities after\n  normalizing for the total weight leaving the state. In all cases, finality is\n  treated as a transition to a super-final state.\n\n  Args:\n    ifst: The input FST.\n    npath: The number of random paths to generate.\n    seed: An optional seed value for random path generation; if zero, the\n        current time and process ID is used.\n    select: A string matching a known random arc selection type; one of:\n        \"uniform\", \"log_prob\", \"fast_log_prob\".\n    max_length: The maximum length of each random path.\n    weighted: Should the output be weighted by path count?\n    remove_total_weight: Should the total weight be removed (ignored when\n        `weighted` is False)?\n\n  Returns:\n    An Fst containing one or more random paths.\n\n  See also: `randequivalent`.\n  ";
+static char __pyx_doc_9pywrapfst_40randgen[] = "\n  randgen(ifst, npath=1, seed=0, select=\"uniform\", max_length=2147483647,\n          weight=False, remove_total_weight=False)\n\n  Randomly generate successful paths in an FST.\n\n  This operation randomly generates a set of successful paths in the input FST.\n  This relies on a mechanism for selecting arcs, specified using the `select`\n  argument. The default selector, \"uniform\", randomly selects a transition\n  using a uniform distribution. The \"log_prob\" selector randomly selects a\n  transition w.r.t. the weights treated as negative log probabilities after\n  normalizing for the total weight leaving the state. In all cases, finality is\n  treated as a transition to a super-final state.\n\n  Args:\n    ifst: The input FST.\n    npath: The number of random paths to generate.\n    seed: An optional seed value for random path generation; if zero, the\n        current time and process ID is used.\n    select: A string matching a known random arc selection type; one of:\n        \"uniform\", \"log_prob\", \"fast_log_prob\".\n    max_length: The maximum length of each random path.\n    weighted: Should the output be weighted by path count?\n    remove_total_weight: Should the total weight be removed (ignored when\n        `weighted` is False)?\n\n  Returns:\n    An FST containing one or more random paths.\n\n  See also: `randequivalent`.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_41randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
   __pyx_t_10basictypes_int32 __pyx_v_npath;
@@ -39380,7 +39025,7 @@ static PyObject *__pyx_pw_9pywrapfst_41randgen(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, 3766, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3787, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39397,26 +39042,26 @@ static PyObject *__pyx_pw_9pywrapfst_41randgen(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, 3767, __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, 3788, __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, 3768, __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, 3789, __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, 3770, __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, 3791, __pyx_L3_error)
     } else {
-      __pyx_v_max_length = __pyx_k__50;
+      __pyx_v_max_length = __pyx_k__54;
     }
     if (values[5]) {
-      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3771, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3792, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3771
+      /* "pywrapfst.pyx":3792
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,             # <<<<<<<<<<<<<<
@@ -39426,10 +39071,10 @@ static PyObject *__pyx_pw_9pywrapfst_41randgen(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, 3772, __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, 3793, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3772
+      /* "pywrapfst.pyx":3793
  *                           int32 max_length=INT32_MAX,
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
@@ -39441,16 +39086,16 @@ static PyObject *__pyx_pw_9pywrapfst_41randgen(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, 3766, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3787, __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, 3766, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3787, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_40randgen(__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":3766
+  /* "pywrapfst.pyx":3787
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -39481,7 +39126,7 @@ static PyObject *__pyx_pf_9pywrapfst_40randgen(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, 3766, __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, 3787, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39498,7 +39143,7 @@ static PyObject *__pyx_pf_9pywrapfst_40randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3816
+/* "pywrapfst.pyx":3837
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -39511,7 +39156,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":3819
+  /* "pywrapfst.pyx":3840
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -39559,26 +39204,26 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     }
   }
 
-  /* "pywrapfst.pyx":3861
+  /* "pywrapfst.pyx":3882
  *   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, 3861, __pyx_L1_error)
+  __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3882, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_it = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3862
+  /* "pywrapfst.pyx":3883
  *   cdef _Fst ifst
  *   it = iter(pairs)
  *   (root_label, ifst) = next(it)             # <<<<<<<<<<<<<<
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  */
-  __pyx_t_1 = __Pyx_PyIter_Next(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3862, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyIter_Next(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3883, __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;
@@ -39590,7 +39235,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, 3862, __pyx_L1_error)
+      __PYX_ERR(0, 3883, __pyx_L1_error)
     }
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
     if (likely(PyTuple_CheckExact(sequence))) {
@@ -39603,15 +39248,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, 3862, __pyx_L1_error)
+    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3883, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3862, __pyx_L1_error)
+    __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3883, __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, 3862, __pyx_L1_error)
+    __pyx_t_4 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3883, __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;
@@ -39619,7 +39264,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, 3862, __pyx_L1_error)
+    if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < 0) __PYX_ERR(0, 3883, __pyx_L1_error)
     __pyx_t_5 = NULL;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     goto __pyx_L4_unpacking_done;
@@ -39627,17 +39272,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, 3862, __pyx_L1_error)
+    __PYX_ERR(0, 3883, __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, 3862, __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, 3883, __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, 3862, __pyx_L1_error)
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3883, __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":3863
+  /* "pywrapfst.pyx":3884
  *   it = iter(pairs)
  *   (root_label, ifst) = next(it)
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))             # <<<<<<<<<<<<<<
@@ -39646,22 +39291,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 '%s'", "_fst");
-    __PYX_ERR(0, 3863, __pyx_L1_error)
+    __PYX_ERR(0, 3884, __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, 3863, __pyx_L1_error)
+    __PYX_ERR(0, 3884, __pyx_L1_error)
   }
   try {
     __pyx_v__pairs.push_back(__pyx_t_7);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 3863, __pyx_L1_error)
+    __PYX_ERR(0, 3884, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3864
+  /* "pywrapfst.pyx":3885
  *   (root_label, ifst) = next(it)
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -39670,11 +39315,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3864, __pyx_L1_error)
+    __PYX_ERR(0, 3885, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3865
+  /* "pywrapfst.pyx":3886
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
@@ -39685,26 +39330,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, 3865, __pyx_L1_error)
+    __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_it); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3886, __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, 3865, __pyx_L1_error)
+    __pyx_t_9 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 3886, __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, 3865, __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, 3886, __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, 3865, __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, 3886, __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, 3865, __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, 3886, __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, 3865, __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, 3886, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         #endif
       }
@@ -39714,7 +39359,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 3865, __pyx_L1_error)
+          else __PYX_ERR(0, 3886, __pyx_L1_error)
         }
         break;
       }
@@ -39730,7 +39375,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, 3865, __pyx_L1_error)
+        __PYX_ERR(0, 3886, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -39743,15 +39388,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, 3865, __pyx_L1_error)
+      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3886, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
-      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3865, __pyx_L1_error)
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3886, __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, 3865, __pyx_L1_error)
+      __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 3886, __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;
@@ -39759,7 +39404,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, 3865, __pyx_L1_error)
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_10), 2) < 0) __PYX_ERR(0, 3886, __pyx_L1_error)
       __pyx_t_5 = NULL;
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       goto __pyx_L8_unpacking_done;
@@ -39767,17 +39412,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, 3865, __pyx_L1_error)
+      __PYX_ERR(0, 3886, __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, 3865, __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, 3886, __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, 3865, __pyx_L1_error)
+    if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 3886, __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":3866
+    /* "pywrapfst.pyx":3887
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   for (label, ifst) in it:
  *     _pairs.push_back(fst.LabelFstClassPair(label, ifst._fst.get()))             # <<<<<<<<<<<<<<
@@ -39786,22 +39431,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 '%s'", "_fst");
-      __PYX_ERR(0, 3866, __pyx_L1_error)
+      __PYX_ERR(0, 3887, __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, 3866, __pyx_L1_error)
+      __PYX_ERR(0, 3887, __pyx_L1_error)
     }
     try {
       __pyx_v__pairs.push_back(__pyx_t_7);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3866, __pyx_L1_error)
+      __PYX_ERR(0, 3887, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3865
+    /* "pywrapfst.pyx":3886
  *   _pairs.push_back(fst.LabelFstClassPair(root_label, ifst._fst.get()))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   for (label, ifst) in it:             # <<<<<<<<<<<<<<
@@ -39811,45 +39456,45 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3868
+  /* "pywrapfst.pyx":3889
  *     _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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3868, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3889, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3867
+  /* "pywrapfst.pyx":3888
  *   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, 3867, __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, 3888, __pyx_L1_error)
   __pyx_v_cal = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3870
+  /* "pywrapfst.pyx":3891
  *       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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3870, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3891, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3869
+  /* "pywrapfst.pyx":3890
  *   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, 3869, __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, 3890, __pyx_L1_error)
   __pyx_v_ral = __pyx_t_12;
 
-  /* "pywrapfst.pyx":3872
+  /* "pywrapfst.pyx":3893
  *       tostring(return_arc_labeling), epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))             # <<<<<<<<<<<<<<
@@ -39858,7 +39503,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":3873
+  /* "pywrapfst.pyx":3894
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst, deref(opts))             # <<<<<<<<<<<<<<
@@ -39867,7 +39512,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   fst::script::Replace(__pyx_v__pairs, __pyx_v_tfst, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3874
+  /* "pywrapfst.pyx":3895
  *   opts.reset(new fst.ReplaceOptions(root_label, cal, ral, return_label))
  *   fst.Replace(_pairs, tfst, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -39875,13 +39520,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)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3874, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3895, __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":3816
+  /* "pywrapfst.pyx":3837
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -39962,7 +39607,7 @@ static PyObject *__pyx_pw_9pywrapfst_43replace(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, 3816, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3837, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39979,10 +39624,10 @@ static PyObject *__pyx_pw_9pywrapfst_43replace(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, 3819, __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, 3840, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3819
+      /* "pywrapfst.pyx":3840
  *                           call_arc_labeling=b"input",
  *                           return_arc_labeling=b"neither",
  *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
@@ -39992,14 +39637,14 @@ static PyObject *__pyx_pw_9pywrapfst_43replace(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, 3820, __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, 3841, __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, 3816, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3837, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -40007,7 +39652,7 @@ static PyObject *__pyx_pw_9pywrapfst_43replace(PyObject *__pyx_self, PyObject *_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_42replace(__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":3816
+  /* "pywrapfst.pyx":3837
  * 
  * 
  * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
@@ -40032,7 +39677,7 @@ static PyObject *__pyx_pf_9pywrapfst_42replace(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, 3816, __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, 3837, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40049,7 +39694,7 @@ static PyObject *__pyx_pf_9pywrapfst_42replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3877
+/* "pywrapfst.pyx":3898
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40071,7 +39716,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
     }
   }
 
-  /* "pywrapfst.pyx":3896
+  /* "pywrapfst.pyx":3917
  *     A reversed FST.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -40080,11 +39725,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 '%s'", "arc_type");
-    __PYX_ERR(0, 3896, __pyx_L1_error)
+    __PYX_ERR(0, 3917, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3897
+  /* "pywrapfst.pyx":3918
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.Reverse(deref(ifst._fst), tfst, require_superinitial)             # <<<<<<<<<<<<<<
@@ -40093,11 +39738,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 '%s'", "_fst");
-    __PYX_ERR(0, 3897, __pyx_L1_error)
+    __PYX_ERR(0, 3918, __pyx_L1_error)
   }
   fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":3898
+  /* "pywrapfst.pyx":3919
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.Reverse(deref(ifst._fst), tfst, require_superinitial)
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -40105,13 +39750,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)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3898, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3919, __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":3877
+  /* "pywrapfst.pyx":3898
  * 
  * 
  * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -40163,7 +39808,7 @@ static PyObject *__pyx_pw_9pywrapfst_45reverse(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, 3877, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 3898, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40175,20 +39820,20 @@ static PyObject *__pyx_pw_9pywrapfst_45reverse(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, 3877, __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, 3898, __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, 3877, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3898, __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, 3877, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3898, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_44reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
@@ -40209,7 +39854,7 @@ static PyObject *__pyx_pf_9pywrapfst_44reverse(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, 3877, __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, 3898, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40226,7 +39871,7 @@ static PyObject *__pyx_pf_9pywrapfst_44reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3901
+/* "pywrapfst.pyx":3922
  * 
  * 
  * cpdef _MutableFst rmepsilon(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40237,7 +39882,7 @@ static PyObject *__pyx_pf_9pywrapfst_44reverse(CYTHON_UNUSED PyObject *__pyx_sel
 static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_rmepsilon *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":3902
+  /* "pywrapfst.pyx":3923
  * 
  * cpdef _MutableFst rmepsilon(_Fst ifst,
  *                             bool connect=True,             # <<<<<<<<<<<<<<
@@ -40245,11 +39890,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  *                             int64 nstate=fst.kNoStateId,
  */
   bool __pyx_v_connect = ((bool)1);
-  float __pyx_v_delta = __pyx_k__51;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__52;
+  float __pyx_v_delta = __pyx_k__55;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__56;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":3906
+  /* "pywrapfst.pyx":3927
  *                             int64 nstate=fst.kNoStateId,
  *                             queue_type=b"auto",
  *                             bool reverse=False,             # <<<<<<<<<<<<<<
@@ -40258,7 +39903,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  */
   bool __pyx_v_reverse = ((bool)0);
 
-  /* "pywrapfst.pyx":3907
+  /* "pywrapfst.pyx":3928
  *                             queue_type=b"auto",
  *                             bool reverse=False,
  *                             weight=None):             # <<<<<<<<<<<<<<
@@ -40297,7 +39942,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
     }
   }
 
-  /* "pywrapfst.pyx":3931
+  /* "pywrapfst.pyx":3952
  *     An equivalent FST with no epsilon transitions.
  *   """
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -40306,22 +39951,22 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "weight_type");
-    __PYX_ERR(0, 3931, __pyx_L1_error)
+    __PYX_ERR(0, 3952, __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, 3931, __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, 3952, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3933
+  /* "pywrapfst.pyx":3954
  *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   cdef unique_ptr[fst.RmEpsilonOptions] opts
  *   opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
  *                                       delta, connect, wc, nstate))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3933, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3933, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3954, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3954, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3934
+  /* "pywrapfst.pyx":3955
  *   cdef unique_ptr[fst.RmEpsilonOptions] opts
  *   opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  *                                       delta, connect, wc, nstate))             # <<<<<<<<<<<<<<
@@ -40330,7 +39975,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  */
   __pyx_v_opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_delta, __pyx_v_connect, __pyx_v_wc, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":3935
+  /* "pywrapfst.pyx":3956
  *   opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
  *                                       delta, connect, wc, nstate))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -40339,11 +39984,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "arc_type");
-    __PYX_ERR(0, 3935, __pyx_L1_error)
+    __PYX_ERR(0, 3956, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":3936
+  /* "pywrapfst.pyx":3957
  *                                       delta, connect, wc, nstate))
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.RmEpsilon(deref(ifst._fst), tfst, reverse, deref(opts))             # <<<<<<<<<<<<<<
@@ -40352,11 +39997,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 3936, __pyx_L1_error)
+    __PYX_ERR(0, 3957, __pyx_L1_error)
   }
   fst::script::RmEpsilon((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_reverse, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3937
+  /* "pywrapfst.pyx":3958
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.RmEpsilon(deref(ifst._fst), tfst, reverse, deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -40364,13 +40009,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_rmepsilon(str
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3937, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3958, __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":3901
+  /* "pywrapfst.pyx":3922
  * 
  * 
  * cpdef _MutableFst rmepsilon(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40408,7 +40053,7 @@ static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":3907
+    /* "pywrapfst.pyx":3928
  *                             queue_type=b"auto",
  *                             bool reverse=False,
  *                             weight=None):             # <<<<<<<<<<<<<<
@@ -40467,7 +40112,7 @@ static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 3901, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 3922, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40484,10 +40129,10 @@ static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)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, 3902, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3923, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3902
+      /* "pywrapfst.pyx":3923
  * 
  * cpdef _MutableFst rmepsilon(_Fst ifst,
  *                             bool connect=True,             # <<<<<<<<<<<<<<
@@ -40497,21 +40142,21 @@ static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject
       __pyx_v_connect = ((bool)1);
     }
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3903, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3924, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__51;
+      __pyx_v_delta = __pyx_k__55;
     }
     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, 3904, __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, 3925, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__52;
+      __pyx_v_nstate = __pyx_k__56;
     }
     __pyx_v_queue_type = values[4];
     if (values[5]) {
-      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3906, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3927, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3906
+      /* "pywrapfst.pyx":3927
  *                             int64 nstate=fst.kNoStateId,
  *                             queue_type=b"auto",
  *                             bool reverse=False,             # <<<<<<<<<<<<<<
@@ -40524,16 +40169,16 @@ static PyObject *__pyx_pw_9pywrapfst_47rmepsilon(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3901, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3922, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.rmepsilon", __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, 3901, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3922, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_46rmepsilon(__pyx_self, __pyx_v_ifst, __pyx_v_connect, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3901
+  /* "pywrapfst.pyx":3922
  * 
  * 
  * cpdef _MutableFst rmepsilon(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40564,7 +40209,7 @@ static PyObject *__pyx_pf_9pywrapfst_46rmepsilon(CYTHON_UNUSED PyObject *__pyx_s
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.reverse = __pyx_v_reverse;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_rmepsilon(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3901, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_rmepsilon(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3922, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40581,7 +40226,7 @@ static PyObject *__pyx_pf_9pywrapfst_46rmepsilon(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3943
+/* "pywrapfst.pyx":3964
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40590,11 +40235,11 @@ static PyObject *__pyx_pf_9pywrapfst_46rmepsilon(CYTHON_UNUSED PyObject *__pyx_s
  */
 
 static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__53;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__54;
+  float __pyx_v_delta = __pyx_k__57;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__58;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":3945
+  /* "pywrapfst.pyx":3966
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *     float delta=fst.kDelta, int64 nstate=fst.kNoStateId, queue_type=b"auto",
  *     bool reverse=False) except *:             # <<<<<<<<<<<<<<
@@ -40626,7 +40271,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     }
   }
 
-  /* "pywrapfst.pyx":3947
+  /* "pywrapfst.pyx":3968
  *     bool reverse=False) except *:
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -40637,11 +40282,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, 3947, __pyx_L1_error)
+    __PYX_ERR(0, 3968, __pyx_L1_error)
   }
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":3951
+  /* "pywrapfst.pyx":3972
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40651,7 +40296,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_t_2 = (__pyx_v_reverse != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3954
+    /* "pywrapfst.pyx":3975
  *     # 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)             # <<<<<<<<<<<<<<
@@ -40660,11 +40305,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 '%s'", "_fst");
-      __PYX_ERR(0, 3954, __pyx_L1_error)
+      __PYX_ERR(0, 3975, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":3951
+    /* "pywrapfst.pyx":3972
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -40674,7 +40319,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":3956
+  /* "pywrapfst.pyx":3977
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -40683,17 +40328,17 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":3957
+    /* "pywrapfst.pyx":3978
  *   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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3957, __pyx_L1_error)
-    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3957, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3978, __pyx_L1_error)
+    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3978, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3956
+    /* "pywrapfst.pyx":3977
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -40702,7 +40347,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":3959
+    /* "pywrapfst.pyx":3980
  *         _get_queue_type(tostring(queue_type)), fst.ANY_ARC_FILTER, nstate,
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -40711,13 +40356,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 '%s'", "_fst");
-      __PYX_ERR(0, 3959, __pyx_L1_error)
+      __PYX_ERR(0, 3980, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), (*__pyx_v_opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":3960
+  /* "pywrapfst.pyx":3981
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
  *   return distance.release()             # <<<<<<<<<<<<<<
@@ -40727,7 +40372,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_r = __pyx_v_distance.release();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3943
+  /* "pywrapfst.pyx":3964
  * 
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40744,7 +40389,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3963
+/* "pywrapfst.pyx":3984
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40808,7 +40453,7 @@ static PyObject *__pyx_pw_9pywrapfst_49shortestdistance(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, 3963, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 3984, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40823,21 +40468,21 @@ static PyObject *__pyx_pw_9pywrapfst_49shortestdistance(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, 3964, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3985, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__55;
+      __pyx_v_delta = __pyx_k__59;
     }
     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, 3965, __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, 3986, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__56;
+      __pyx_v_nstate = __pyx_k__60;
     }
     __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, 3967, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3988, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3967
+      /* "pywrapfst.pyx":3988
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
@@ -40849,16 +40494,16 @@ static PyObject *__pyx_pw_9pywrapfst_49shortestdistance(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, 3963, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3984, __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, 3963, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 3984, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_48shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
 
-  /* "pywrapfst.pyx":3963
+  /* "pywrapfst.pyx":3984
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -40891,7 +40536,7 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
   int __pyx_t_7;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":3996
+  /* "pywrapfst.pyx":4017
  *   """
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))             # <<<<<<<<<<<<<<
@@ -40903,10 +40548,10 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(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, 3996, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4017, __pyx_L1_error)
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":3998
+  /* "pywrapfst.pyx":4019
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
  *   # Packs the distances, as strings, into a Python list.
  *   cdef string weight_type = ifst.weight_type()             # <<<<<<<<<<<<<<
@@ -40915,23 +40560,23 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "weight_type");
-    __PYX_ERR(0, 3998, __pyx_L1_error)
+    __PYX_ERR(0, 4019, __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":3999
+  /* "pywrapfst.pyx":4020
  *   # Packs the distances, as strings, into a Python list.
  *   cdef string weight_type = ifst.weight_type()
  *   result = []             # <<<<<<<<<<<<<<
  *   # This is just the Cython version of the normal vector iteration idiom.
  *   cdef vector[fst.WeightClass].iterator it = distance.get().begin()
  */
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3999, __pyx_L1_error)
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4020, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_v_result = ((PyObject*)__pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":4001
+  /* "pywrapfst.pyx":4022
  *   result = []
  *   # This is just the Cython version of the normal vector iteration idiom.
  *   cdef vector[fst.WeightClass].iterator it = distance.get().begin()             # <<<<<<<<<<<<<<
@@ -40940,7 +40585,7 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
  */
   __pyx_v_it = __pyx_v_distance.get()->begin();
 
-  /* "pywrapfst.pyx":4002
+  /* "pywrapfst.pyx":4023
  *   # This is just the Cython version of the normal vector iteration idiom.
  *   cdef vector[fst.WeightClass].iterator it = distance.get().begin()
  *   while it != distance.get().end():             # <<<<<<<<<<<<<<
@@ -40951,18 +40596,18 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
     __pyx_t_4 = ((__pyx_v_it != __pyx_v_distance.get()->end()) != 0);
     if (!__pyx_t_4) break;
 
-    /* "pywrapfst.pyx":4003
+    /* "pywrapfst.pyx":4024
  *   cdef vector[fst.WeightClass].iterator it = distance.get().begin()
  *   while it != distance.get().end():
  *     result.append(Weight(weight_type, deref(it).ToString()))             # <<<<<<<<<<<<<<
  *     inc(it)
  *   return result
  */
-    __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4003, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4024, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __pyx_convert_PyBytes_string_to_py_std__in_string((*__pyx_v_it).ToString()); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4003, __pyx_L1_error)
+    __pyx_t_5 = __pyx_convert_PyBytes_string_to_py_std__in_string((*__pyx_v_it).ToString()); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4024, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4003, __pyx_L1_error)
+    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4024, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_GIVEREF(__pyx_t_3);
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3);
@@ -40970,13 +40615,13 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
     PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4003, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4024, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_result, __pyx_t_5); if (unlikely(__pyx_t_7 == -1)) __PYX_ERR(0, 4003, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_result, __pyx_t_5); if (unlikely(__pyx_t_7 == -1)) __PYX_ERR(0, 4024, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-    /* "pywrapfst.pyx":4004
+    /* "pywrapfst.pyx":4025
  *   while it != distance.get().end():
  *     result.append(Weight(weight_type, deref(it).ToString()))
  *     inc(it)             # <<<<<<<<<<<<<<
@@ -40986,7 +40631,7 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
     (++__pyx_v_it);
   }
 
-  /* "pywrapfst.pyx":4005
+  /* "pywrapfst.pyx":4026
  *     result.append(Weight(weight_type, deref(it).ToString()))
  *     inc(it)
  *   return result             # <<<<<<<<<<<<<<
@@ -40998,7 +40643,7 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3963
+  /* "pywrapfst.pyx":3984
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41020,7 +40665,7 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4008
+/* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41030,12 +40675,12 @@ static PyObject *__pyx_pf_9pywrapfst_48shortestdistance(CYTHON_UNUSED PyObject *
 
 static PyObject *__pyx_pw_9pywrapfst_51shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_shortestpath *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__57;
+  float __pyx_v_delta = __pyx_k__61;
   __pyx_t_10basictypes_int32 __pyx_v_nshortest = ((__pyx_t_10basictypes_int32)1);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__58;
+  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__62;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":4013
+  /* "pywrapfst.pyx":4034
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -41044,7 +40689,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4014
+  /* "pywrapfst.pyx":4035
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -41085,7 +40730,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
     }
   }
 
-  /* "pywrapfst.pyx":4045
+  /* "pywrapfst.pyx":4066
  *     An FST containing the n-shortest paths.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -41094,11 +40739,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 '%s'", "arc_type");
-    __PYX_ERR(0, 4045, __pyx_L1_error)
+    __PYX_ERR(0, 4066, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":4047
+  /* "pywrapfst.pyx":4068
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -41109,11 +40754,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
     __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 4047, __pyx_L1_error)
+    __PYX_ERR(0, 4068, __pyx_L1_error)
   }
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4049
+  /* "pywrapfst.pyx":4070
  *   distance.reset(new vector[fst.WeightClass]())
  *   # 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)             # <<<<<<<<<<<<<<
@@ -41122,22 +40767,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 '%s'", "weight_type");
-    __PYX_ERR(0, 4049, __pyx_L1_error)
+    __PYX_ERR(0, 4070, __pyx_L1_error)
   }
-  __pyx_t_2 = __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, 4049, __pyx_L1_error)
+  __pyx_t_2 = __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, 4070, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4051
+  /* "pywrapfst.pyx":4072
  *   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, False, delta,
  *                                          False, wc, nstate))
  */
-  __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4051, __pyx_L1_error)
-  __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4051, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4072, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4072, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4053
+  /* "pywrapfst.pyx":4074
  *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
  *                                          nshortest, unique, False, delta,
  *                                          False, wc, nstate))             # <<<<<<<<<<<<<<
@@ -41146,7 +40791,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   __pyx_v_opts.reset(new fst::script::ShortestPathOptions(__pyx_t_4, __pyx_v_nshortest, __pyx_v_unique, 0, __pyx_v_delta, 0, __pyx_v_wc, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":4054
+  /* "pywrapfst.pyx":4075
  *                                          nshortest, unique, False, delta,
  *                                          False, wc, nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst, distance.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -41155,11 +40800,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 '%s'", "_fst");
-    __PYX_ERR(0, 4054, __pyx_L1_error)
+    __PYX_ERR(0, 4075, __pyx_L1_error)
   }
   fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v_tfst, __pyx_v_distance.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":4055
+  /* "pywrapfst.pyx":4076
  *                                          False, wc, nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst, distance.get(), deref(opts))
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -41167,13 +40812,13 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_5 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4055, __pyx_L1_error)
+  __pyx_t_5 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4076, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_5);
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4008
+  /* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41211,7 +40856,7 @@ static PyObject *__pyx_pw_9pywrapfst_51shortestpath(PyObject *__pyx_self, PyObje
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":4014
+    /* "pywrapfst.pyx":4035
  *                                queue_type=b"auto",
  *                                bool unique=False,
  *                                weight=None):             # <<<<<<<<<<<<<<
@@ -41270,7 +40915,7 @@ static PyObject *__pyx_pw_9pywrapfst_51shortestpath(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, 4008, __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)) {
@@ -41287,26 +40932,26 @@ static PyObject *__pyx_pw_9pywrapfst_51shortestpath(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, 4009, __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__57;
+      __pyx_v_delta = __pyx_k__61;
     }
     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, 4010, __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, 4011, __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__58;
+      __pyx_v_nstate = __pyx_k__62;
     }
     __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, 4013, __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":4013
+      /* "pywrapfst.pyx":4034
  *                                int64 nstate=fst.kNoStateId,
  *                                queue_type=b"auto",
  *                                bool unique=False,             # <<<<<<<<<<<<<<
@@ -41319,16 +40964,16 @@ static PyObject *__pyx_pw_9pywrapfst_51shortestpath(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, 4008, __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, 4008, __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_50shortestpath(__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":4008
+  /* "pywrapfst.pyx":4029
  * 
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
@@ -41359,7 +41004,7 @@ static PyObject *__pyx_pf_9pywrapfst_50shortestpath(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, 4008, __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;
@@ -41376,7 +41021,7 @@ static PyObject *__pyx_pf_9pywrapfst_50shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4058
+/* "pywrapfst.pyx":4079
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41392,7 +41037,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":4081
+  /* "pywrapfst.pyx":4102
  *   See also: `arcmap`.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, None)             # <<<<<<<<<<<<<<
@@ -41404,13 +41049,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
   __pyx_t_2.delta = fst::kDelta;
   __pyx_t_2.map_type = __pyx_v_map_type;
   __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, 4081, __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":4058
+  /* "pywrapfst.pyx":4079
  * 
  * 
  * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -41458,11 +41103,11 @@ static PyObject *__pyx_pw_9pywrapfst_53statemap(PyObject *__pyx_self, PyObject *
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_map_type)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4058, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4079, __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, 4058, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4079, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -41475,13 +41120,13 @@ static PyObject *__pyx_pw_9pywrapfst_53statemap(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, 4058, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4079, __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, 4058, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4079, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_52statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
@@ -41499,7 +41144,7 @@ static PyObject *__pyx_pf_9pywrapfst_52statemap(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, 4058, __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, 4079, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41516,7 +41161,7 @@ static PyObject *__pyx_pf_9pywrapfst_52statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4084
+/* "pywrapfst.pyx":4105
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41532,7 +41177,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4103
+  /* "pywrapfst.pyx":4124
  *     An equivalent synchronized FST.
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())             # <<<<<<<<<<<<<<
@@ -41541,11 +41186,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 '%s'", "arc_type");
-    __PYX_ERR(0, 4103, __pyx_L1_error)
+    __PYX_ERR(0, 4124, __pyx_L1_error)
   }
   __pyx_v_tfst = new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0));
 
-  /* "pywrapfst.pyx":4104
+  /* "pywrapfst.pyx":4125
  *   """
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.Synchronize(deref(ifst._fst), tfst)             # <<<<<<<<<<<<<<
@@ -41554,11 +41199,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 '%s'", "_fst");
-    __PYX_ERR(0, 4104, __pyx_L1_error)
+    __PYX_ERR(0, 4125, __pyx_L1_error)
   }
   fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v_tfst);
 
-  /* "pywrapfst.pyx":4105
+  /* "pywrapfst.pyx":4126
  *   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst.arc_type())
  *   fst.Synchronize(deref(ifst._fst), tfst)
  *   return _init_MutableFst(tfst)             # <<<<<<<<<<<<<<
@@ -41566,13 +41211,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)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4105, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4126, __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":4084
+  /* "pywrapfst.pyx":4105
  * 
  * 
  * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
@@ -41598,7 +41243,7 @@ static PyObject *__pyx_pw_9pywrapfst_55synchronize(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, 4084, __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_54synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
 
   /* function exit code */
@@ -41616,7 +41261,7 @@ static PyObject *__pyx_pf_9pywrapfst_54synchronize(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, 4084, __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;
@@ -41633,7 +41278,7 @@ static PyObject *__pyx_pf_9pywrapfst_54synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4162
+/* "pywrapfst.pyx":4183
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -41661,7 +41306,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":4165
+    /* "pywrapfst.pyx":4186
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -41670,7 +41315,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":4166
+    /* "pywrapfst.pyx":4187
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -41679,7 +41324,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":4167
+    /* "pywrapfst.pyx":4188
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -41758,7 +41403,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, 4162, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4183, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41777,23 +41422,23 @@ 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, 4163, __pyx_L3_error)
+      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4184, __pyx_L3_error)
     } else {
-      __pyx_v_fst_type = __pyx_k__59;
+      __pyx_v_fst_type = __pyx_k__63;
     }
     if (values[1]) {
-      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4164, __pyx_L3_error)
+      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4185, __pyx_L3_error)
     } else {
-      __pyx_v_arc_type = __pyx_k__60;
+      __pyx_v_arc_type = __pyx_k__64;
     }
     __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[2]);
     __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, 4168, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4189, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4168
+      /* "pywrapfst.pyx":4189
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -41803,10 +41448,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, 4169, __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, 4190, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4169
+      /* "pywrapfst.pyx":4190
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -41816,10 +41461,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, 4170, __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, 4191, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4170
+      /* "pywrapfst.pyx":4191
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -41829,10 +41474,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, 4171, __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, 4192, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4171
+      /* "pywrapfst.pyx":4192
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -41842,10 +41487,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, 4172, __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, 4193, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4172
+      /* "pywrapfst.pyx":4193
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -41857,18 +41502,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, 4162, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4183, __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, 4165, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4166, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4167, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4186, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4187, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4188, __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":4162
+  /* "pywrapfst.pyx":4183
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -41895,7 +41540,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   fst::SymbolTable *__pyx_t_5;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4173
+  /* "pywrapfst.pyx":4194
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -41904,45 +41549,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 '%s'", "_sstrm");
-    __PYX_ERR(0, 4173, __pyx_L1_error)
+    __PYX_ERR(0, 4194, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4174
+  /* "pywrapfst.pyx":4195
  *                 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_PyBytes_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4174, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4195, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4174, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4195, __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 '%s'", "_fst_type");
-    __PYX_ERR(0, 4174, __pyx_L1_error)
+    __PYX_ERR(0, 4195, __pyx_L1_error)
   }
   __pyx_v_self->_fst_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4175
+  /* "pywrapfst.pyx":4196
  *     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_PyBytes_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4175, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_arc_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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4175, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1, NULL); 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 '%s'", "_arc_type");
-    __PYX_ERR(0, 4175, __pyx_L1_error)
+    __PYX_ERR(0, 4196, __pyx_L1_error)
   }
   __pyx_v_self->_arc_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4176
+  /* "pywrapfst.pyx":4197
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
@@ -41951,11 +41596,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 '%s'", "_isymbols");
-    __PYX_ERR(0, 4176, __pyx_L1_error)
+    __PYX_ERR(0, 4197, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4177
+  /* "pywrapfst.pyx":4198
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -41966,7 +41611,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":4178
+    /* "pywrapfst.pyx":4199
  *     self._isymbols = NULL
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table             # <<<<<<<<<<<<<<
@@ -41975,16 +41620,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 '%s'", "_table");
-      __PYX_ERR(0, 4178, __pyx_L1_error)
+      __PYX_ERR(0, 4199, __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 '%s'", "_isymbols");
-      __PYX_ERR(0, 4178, __pyx_L1_error)
+      __PYX_ERR(0, 4199, __pyx_L1_error)
     }
     __pyx_v_self->_isymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4177
+    /* "pywrapfst.pyx":4198
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -41993,7 +41638,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4179
+  /* "pywrapfst.pyx":4200
  *     if isymbols is not None:
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
@@ -42002,11 +41647,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 '%s'", "_osymbols");
-    __PYX_ERR(0, 4179, __pyx_L1_error)
+    __PYX_ERR(0, 4200, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4180
+  /* "pywrapfst.pyx":4201
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -42017,7 +41662,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":4181
+    /* "pywrapfst.pyx":4202
  *     self._osymbols = NULL
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table             # <<<<<<<<<<<<<<
@@ -42026,16 +41671,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 '%s'", "_table");
-      __PYX_ERR(0, 4181, __pyx_L1_error)
+      __PYX_ERR(0, 4202, __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 '%s'", "_osymbols");
-      __PYX_ERR(0, 4181, __pyx_L1_error)
+      __PYX_ERR(0, 4202, __pyx_L1_error)
     }
     __pyx_v_self->_osymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4180
+    /* "pywrapfst.pyx":4201
  *       self._isymbols = isymbols._table
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -42044,7 +41689,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4182
+  /* "pywrapfst.pyx":4203
  *     if osymbols is not None:
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -42053,11 +41698,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 '%s'", "_ssymbols");
-    __PYX_ERR(0, 4182, __pyx_L1_error)
+    __PYX_ERR(0, 4203, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4183
+  /* "pywrapfst.pyx":4204
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42068,7 +41713,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":4184
+    /* "pywrapfst.pyx":4205
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
@@ -42077,16 +41722,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 '%s'", "_table");
-      __PYX_ERR(0, 4184, __pyx_L1_error)
+      __PYX_ERR(0, 4205, __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 '%s'", "_ssymbols");
-      __PYX_ERR(0, 4184, __pyx_L1_error)
+      __PYX_ERR(0, 4205, __pyx_L1_error)
     }
     __pyx_v_self->_ssymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4183
+    /* "pywrapfst.pyx":4204
  *       self._osymbols = osymbols._table
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -42095,7 +41740,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4185
+  /* "pywrapfst.pyx":4206
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
@@ -42104,11 +41749,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 '%s'", "_acceptor");
-    __PYX_ERR(0, 4185, __pyx_L1_error)
+    __PYX_ERR(0, 4206, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4186
+  /* "pywrapfst.pyx":4207
  *       self._ssymbols = ssymbols._table
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
@@ -42117,11 +41762,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 '%s'", "_keep_isymbols");
-    __PYX_ERR(0, 4186, __pyx_L1_error)
+    __PYX_ERR(0, 4207, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4187
+  /* "pywrapfst.pyx":4208
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -42130,11 +41775,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 '%s'", "_keep_osymbols");
-    __PYX_ERR(0, 4187, __pyx_L1_error)
+    __PYX_ERR(0, 4208, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4188
+  /* "pywrapfst.pyx":4209
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -42143,11 +41788,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 '%s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4188, __pyx_L1_error)
+    __PYX_ERR(0, 4209, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4189
+  /* "pywrapfst.pyx":4210
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
@@ -42156,11 +41801,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 '%s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4189, __pyx_L1_error)
+    __PYX_ERR(0, 4210, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4162
+  /* "pywrapfst.pyx":4183
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42180,7 +41825,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4191
+/* "pywrapfst.pyx":4212
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42204,7 +41849,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4191, __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, 4212, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_8Compiler_3compile)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -42220,14 +41865,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4191, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4212, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4191, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4212, __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, 4191, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4212, __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;
@@ -42236,7 +41881,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4205
+  /* "pywrapfst.pyx":4226
  *       FstOpError: Compilation failed.
  *     """
  *     cdef fst.FstClass *tfst = fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -42245,31 +41890,31 @@ 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 '%s'", "_sstrm");
-    __PYX_ERR(0, 4205, __pyx_L1_error)
+    __PYX_ERR(0, 4226, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4206
+  /* "pywrapfst.pyx":4227
  *     """
  *     cdef fst.FstClass *tfst = fst.CompileFstInternal(deref(self._sstrm),
  *         "<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,
  */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_pywrapfst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4206, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_pywrapfst); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4227, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst_type");
-    __PYX_ERR(0, 4206, __pyx_L1_error)
+    __PYX_ERR(0, 4227, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_arc_type");
-    __PYX_ERR(0, 4206, __pyx_L1_error)
+    __PYX_ERR(0, 4227, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_isymbols");
-    __PYX_ERR(0, 4206, __pyx_L1_error)
+    __PYX_ERR(0, 4227, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4207
+  /* "pywrapfst.pyx":4228
  *     cdef fst.FstClass *tfst = fst.CompileFstInternal(deref(self._sstrm),
  *         "<pywrapfst>", self._fst_type, self._arc_type, self._isymbols,
  *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,             # <<<<<<<<<<<<<<
@@ -42278,22 +41923,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 '%s'", "_osymbols");
-    __PYX_ERR(0, 4207, __pyx_L1_error)
+    __PYX_ERR(0, 4228, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_ssymbols");
-    __PYX_ERR(0, 4207, __pyx_L1_error)
+    __PYX_ERR(0, 4228, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_acceptor");
-    __PYX_ERR(0, 4207, __pyx_L1_error)
+    __PYX_ERR(0, 4228, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_keep_isymbols");
-    __PYX_ERR(0, 4207, __pyx_L1_error)
+    __PYX_ERR(0, 4228, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4208
+  /* "pywrapfst.pyx":4229
  *         "<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,             # <<<<<<<<<<<<<<
@@ -42302,14 +41947,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 '%s'", "_keep_osymbols");
-    __PYX_ERR(0, 4208, __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 '%s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4208, __pyx_L1_error)
+    __PYX_ERR(0, 4229, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4209
+  /* "pywrapfst.pyx":4230
  *         self._osymbols, self._ssymbols, self._acceptor, self._keep_isymbols,
  *         self._keep_osymbols, self._keep_state_numbering,
  *         self._allow_negative_labels)             # <<<<<<<<<<<<<<
@@ -42318,10 +41963,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 '%s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4209, __pyx_L1_error)
+    __PYX_ERR(0, 4230, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4205
+  /* "pywrapfst.pyx":4226
  *       FstOpError: Compilation failed.
  *     """
  *     cdef fst.FstClass *tfst = fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -42330,7 +41975,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   __pyx_v_tfst = fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_t_5, __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":4210
+  /* "pywrapfst.pyx":4231
  *         self._keep_osymbols, self._keep_state_numbering,
  *         self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -42339,11 +41984,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 '%s'", "_sstrm");
-    __PYX_ERR(0, 4210, __pyx_L1_error)
+    __PYX_ERR(0, 4231, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4211
+  /* "pywrapfst.pyx":4232
  *         self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())
  *     if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -42353,23 +41998,23 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
   __pyx_t_6 = ((__pyx_v_tfst == NULL) != 0);
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4212
+    /* "pywrapfst.pyx":4233
  *     self._sstrm.reset(new stringstream())
  *     if tfst == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
  *     return _init_XFst(tfst)
  * 
  */
-    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4212, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4233, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__61, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4212, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__65, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4233, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 4212, __pyx_L1_error)
+    __PYX_ERR(0, 4233, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4211
+    /* "pywrapfst.pyx":4232
  *         self._allow_negative_labels)
  *     self._sstrm.reset(new stringstream())
  *     if tfst == NULL:             # <<<<<<<<<<<<<<
@@ -42378,7 +42023,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   }
 
-  /* "pywrapfst.pyx":4213
+  /* "pywrapfst.pyx":4234
  *     if tfst == NULL:
  *       raise FstOpError("Compilation failed")
  *     return _init_XFst(tfst)             # <<<<<<<<<<<<<<
@@ -42386,13 +42031,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_2 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4213, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4234, __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":4191
+  /* "pywrapfst.pyx":4212
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
@@ -42434,7 +42079,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, 4191, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4212, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42451,7 +42096,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4215
+/* "pywrapfst.pyx":4236
  *     return _init_XFst(tfst)
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42473,7 +42118,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4215, __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, 4236, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_8Compiler_5write)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -42488,13 +42133,13 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_expression); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4215, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_expression); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4236, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_expression};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4215, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4236, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -42502,19 +42147,19 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_expression};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4215, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4236, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4215, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4236, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_expression);
           __Pyx_GIVEREF(__pyx_v_expression);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_expression);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4215, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4236, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
@@ -42527,7 +42172,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4231
+  /* "pywrapfst.pyx":4252
  *       expression: A string expression to add to compiler string buffer.
  *     """
  *     deref(self._sstrm) << tostring(expression)             # <<<<<<<<<<<<<<
@@ -42536,12 +42181,12 @@ 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 '%s'", "_sstrm");
-    __PYX_ERR(0, 4231, __pyx_L1_error)
+    __PYX_ERR(0, 4252, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4231, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4252, __pyx_L1_error)
   ((*__pyx_v_self->_sstrm) << __pyx_t_6);
 
-  /* "pywrapfst.pyx":4215
+  /* "pywrapfst.pyx":4236
  *     return _init_XFst(tfst)
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -42582,7 +42227,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, 4215, __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, 4236, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42599,7 +42244,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4256
+/* "pywrapfst.pyx":4274
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42635,28 +42280,28 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4257
+  /* "pywrapfst.pyx":4275
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4257, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4275, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4258
+  /* "pywrapfst.pyx":4276
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4258, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4276, __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, 4258, __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, 4276, __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, 4258, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4276, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -42670,14 +42315,14 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
     }
   }
   if (!__pyx_t_5) {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4258, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4276, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_GOTREF(__pyx_t_3);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4258, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4276, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -42686,20 +42331,20 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4258, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4276, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4258, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4276, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
       __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4258, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4276, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -42716,14 +42361,14 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
     }
   }
   if (!__pyx_t_4) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4257, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4275, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4257, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4275, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -42732,20 +42377,20 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4257, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4275, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4257, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4275, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4257, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4275, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -42753,9 +42398,9 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4257, __pyx_L1_error)
+  __PYX_ERR(0, 4275, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4256
+  /* "pywrapfst.pyx":4274
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -42778,7 +42423,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4260
+/* "pywrapfst.pyx":4278
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -42811,7 +42456,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4261
+  /* "pywrapfst.pyx":4279
  * 
  *   def __repr__(self):
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -42819,20 +42464,20 @@ 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_s_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4261, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4279, __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 '%s'", "far_type");
-    __PYX_ERR(0, 4261, __pyx_L1_error)
+    __PYX_ERR(0, 4279, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_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, 4261, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_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, 4279, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4261, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4279, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4261, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4279, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -42850,7 +42495,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_4, __pyx_t_3, __pyx_t_5};
-    __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, 4261, __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, 4279, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -42860,7 +42505,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_4, __pyx_t_3, __pyx_t_5};
-    __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, 4261, __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, 4279, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -42868,7 +42513,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, 4261, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4279, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -42879,7 +42524,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_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4261, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4279, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -42888,7 +42533,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4260
+  /* "pywrapfst.pyx":4278
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -42912,7 +42557,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4264
+/* "pywrapfst.pyx":4282
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
@@ -42958,47 +42603,47 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __Pyx_RefNannySetupContext("open", 0);
   __Pyx_INCREF(__pyx_v_filenames);
 
-  /* "pywrapfst.pyx":4282
+  /* "pywrapfst.pyx":4300
  *       FstIOError: Read failed.
  *     """
  *     filenames = [tostring(filename) for filename in filenames]             # <<<<<<<<<<<<<<
  *     cdef fst.FarReaderClass *tfar = fst.FarReaderClass.Open(filenames)
  *     if tfar == NULL:
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4282, __pyx_L1_error)
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4300, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = __pyx_v_filenames; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
   for (;;) {
     if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 4282, __pyx_L1_error)
+    __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 4300, __pyx_L1_error)
     #else
-    __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4282, __pyx_L1_error)
+    __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4300, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     #endif
     __Pyx_XDECREF_SET(__pyx_v_filename, __pyx_t_4);
     __pyx_t_4 = 0;
-    __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4282, __pyx_L1_error)
-    __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4282, __pyx_L1_error)
+    __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4300, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4300, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 4282, __pyx_L1_error)
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 4300, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF_SET(__pyx_v_filenames, __pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4283
+  /* "pywrapfst.pyx":4301
  *     """
  *     filenames = [tostring(filename) for filename in filenames]
  *     cdef fst.FarReaderClass *tfar = fst.FarReaderClass.Open(filenames)             # <<<<<<<<<<<<<<
  *     if tfar == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filenames))
  */
-  __pyx_t_6 = __pyx_convert_vector_from_py_std_3a__3a_string(__pyx_v_filenames); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4283, __pyx_L1_error)
+  __pyx_t_6 = __pyx_convert_vector_from_py_std_3a__3a_string(__pyx_v_filenames); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4301, __pyx_L1_error)
   __pyx_v_tfar = fst::script::FarReaderClass::Open(__pyx_t_6);
 
-  /* "pywrapfst.pyx":4284
+  /* "pywrapfst.pyx":4302
  *     filenames = [tostring(filename) for filename in filenames]
  *     cdef fst.FarReaderClass *tfar = fst.FarReaderClass.Open(filenames)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -43008,16 +42653,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_t_7 = ((__pyx_v_tfar == NULL) != 0);
   if (__pyx_t_7) {
 
-    /* "pywrapfst.pyx":4285
+    /* "pywrapfst.pyx":4303
  *     cdef fst.FarReaderClass *tfar = fst.FarReaderClass.Open(filenames)
  *     if tfar == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filenames))             # <<<<<<<<<<<<<<
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar)
  */
-    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4285, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4303, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4285, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4303, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_8);
     __pyx_t_9 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) {
@@ -43030,13 +42675,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
       }
     }
     if (!__pyx_t_9) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_filenames); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4285, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_filenames); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4303, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_8)) {
         PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_v_filenames};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
@@ -43044,19 +42689,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_8)) {
         PyObject *__pyx_temp[2] = {__pyx_t_9, __pyx_v_filenames};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_8, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
         __Pyx_GOTREF(__pyx_t_4);
       } else
       #endif
       {
-        __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = NULL;
         __Pyx_INCREF(__pyx_v_filenames);
         __Pyx_GIVEREF(__pyx_v_filenames);
         PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_v_filenames);
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       }
@@ -43073,14 +42718,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
       }
     }
     if (!__pyx_t_8) {
-      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4285, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_4};
-        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -43089,20 +42734,20 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_t_4};
-        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else
       #endif
       {
-        __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __pyx_t_8 = NULL;
         __Pyx_GIVEREF(__pyx_t_4);
         PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_4);
         __pyx_t_4 = 0;
-        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4285, __pyx_L1_error)
+        __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_1);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       }
@@ -43110,9 +42755,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     __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, 4285, __pyx_L1_error)
+    __PYX_ERR(0, 4303, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4284
+    /* "pywrapfst.pyx":4302
  *     filenames = [tostring(filename) for filename in filenames]
  *     cdef fst.FarReaderClass *tfar = fst.FarReaderClass.Open(filenames)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -43121,20 +42766,20 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   }
 
-  /* "pywrapfst.pyx":4286
+  /* "pywrapfst.pyx":4304
  *     if tfar == NULL:
  *       raise FstIOError("Read failed: {!r}".format(filenames))
  *     cdef FarReader result = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
  *     result._reader.reset(tfar)
  *     return result
  */
-  __pyx_t_1 = __pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4286, __pyx_L1_error)
+  __pyx_t_1 = __pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4304, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_FarReader)))) __PYX_ERR(0, 4286, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_9pywrapfst_FarReader)))) __PYX_ERR(0, 4304, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4287
+  /* "pywrapfst.pyx":4305
  *       raise FstIOError("Read failed: {!r}".format(filenames))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar)             # <<<<<<<<<<<<<<
@@ -43143,11 +42788,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 '%s'", "_reader");
-    __PYX_ERR(0, 4287, __pyx_L1_error)
+    __PYX_ERR(0, 4305, __pyx_L1_error)
   }
   __pyx_v_result->_reader.reset(__pyx_v_tfar);
 
-  /* "pywrapfst.pyx":4288
+  /* "pywrapfst.pyx":4306
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar)
  *     return result             # <<<<<<<<<<<<<<
@@ -43159,7 +42804,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4264
+  /* "pywrapfst.pyx":4282
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
@@ -43186,7 +42831,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4291
+/* "pywrapfst.pyx":4309
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -43212,7 +42857,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6__iter__(struct __pyx_obj_9pywr
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":4292
+  /* "pywrapfst.pyx":4310
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -43224,7 +42869,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6__iter__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4291
+  /* "pywrapfst.pyx":4309
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -43239,7 +42884,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6__iter__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4295
+/* "pywrapfst.pyx":4313
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -43270,7 +42915,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":4296
+  /* "pywrapfst.pyx":4314
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -43279,12 +42924,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "done");
-    __PYX_ERR(0, 4296, __pyx_L1_error)
+    __PYX_ERR(0, 4314, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":4297
+    /* "pywrapfst.pyx":4315
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -43292,9 +42937,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  *     cdef _MutableFst f = self.get_fst()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 4297, __pyx_L1_error)
+    __PYX_ERR(0, 4315, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4296
+    /* "pywrapfst.pyx":4314
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -43303,7 +42948,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":4298
+  /* "pywrapfst.pyx":4316
  *     if self.done():
  *       raise StopIteration
  *     cdef string k = self.get_key()             # <<<<<<<<<<<<<<
@@ -43312,11 +42957,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "get_key");
-    __PYX_ERR(0, 4298, __pyx_L1_error)
+    __PYX_ERR(0, 4316, __pyx_L1_error)
   }
   __pyx_v_k = ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_key(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":4299
+  /* "pywrapfst.pyx":4317
  *       raise StopIteration
  *     cdef string k = self.get_key()
  *     cdef _MutableFst f = self.get_fst()             # <<<<<<<<<<<<<<
@@ -43325,15 +42970,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "get_fst");
-    __PYX_ERR(0, 4299, __pyx_L1_error)
+    __PYX_ERR(0, 4317, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4299, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4317, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__MutableFst))))) __PYX_ERR(0, 4299, __pyx_L1_error)
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__MutableFst))))) __PYX_ERR(0, 4317, __pyx_L1_error)
   __pyx_v_f = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":4300
+  /* "pywrapfst.pyx":4318
  *     cdef string k = self.get_key()
  *     cdef _MutableFst f = self.get_fst()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -43342,11 +42987,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "next");
-    __PYX_ERR(0, 4300, __pyx_L1_error)
+    __PYX_ERR(0, 4318, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":4301
+  /* "pywrapfst.pyx":4319
  *     cdef _MutableFst f = self.get_fst()
  *     self.next()
  *     return (k, f)             # <<<<<<<<<<<<<<
@@ -43354,9 +42999,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
  *   cpdef string arc_type(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_k); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4301, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_k); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4319, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4301, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4319, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
@@ -43368,7 +43013,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4295
+  /* "pywrapfst.pyx":4313
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -43389,12 +43034,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8__next__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4303
+/* "pywrapfst.pyx":4321
  *     return (k, f)
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._reader.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -43411,7 +43056,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __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, 4321, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_11arc_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -43426,14 +43071,14 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4303, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4321, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4303, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4321, __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, 4303, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4321, __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;
@@ -43442,26 +43087,26 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4304
- * 
- *   cpdef string arc_type(self):
+  /* "pywrapfst.pyx":4327
+ *     Returns a string indicating the arc type.
+ *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
  * 
  *   cpdef bool done(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_reader");
-    __PYX_ERR(0, 4304, __pyx_L1_error)
+    __PYX_ERR(0, 4327, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4303
+  /* "pywrapfst.pyx":4321
  *     return (k, f)
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._reader.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
   /* function exit code */
@@ -43478,6 +43123,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_9FarReader_10arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -43495,7 +43141,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10arc_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4303, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4321, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43512,7 +43158,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10arc_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4306
+/* "pywrapfst.pyx":4329
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43534,7 +43180,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4306, __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, 4329, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_13done)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -43549,14 +43195,14 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4306, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4329, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4306, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4329, __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, 4306, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4329, __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;
@@ -43565,7 +43211,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4318
+  /* "pywrapfst.pyx":4338
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -43574,12 +43220,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 '%s'", "_reader");
-    __PYX_ERR(0, 4318, __pyx_L1_error)
+    __PYX_ERR(0, 4338, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4306
+  /* "pywrapfst.pyx":4329
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -43602,7 +43248,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_13done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_12done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_12done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_13done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -43620,7 +43266,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12done(struct __pyx_obj_9pywrapf
   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, 4306, __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, 4329, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43637,7 +43283,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12done(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4320
+/* "pywrapfst.pyx":4340
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43659,7 +43305,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4320, __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, 4340, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_15error)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -43674,14 +43320,14 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4320, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4340, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4320, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4340, __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, 4320, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4340, __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;
@@ -43690,7 +43336,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4329
+  /* "pywrapfst.pyx":4349
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -43699,12 +43345,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 '%s'", "_reader");
-    __PYX_ERR(0, 4329, __pyx_L1_error)
+    __PYX_ERR(0, 4349, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4320
+  /* "pywrapfst.pyx":4340
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -43745,7 +43391,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14error(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, 4320, __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, 4340, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43762,7 +43408,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4331
+/* "pywrapfst.pyx":4351
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43784,7 +43430,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4331, __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, 4351, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_17far_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -43799,14 +43445,14 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4331, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4351, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4331, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4351, __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, 4331, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4351, __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;
@@ -43815,7 +43461,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4332
+  /* "pywrapfst.pyx":4352
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
@@ -43824,12 +43470,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 '%s'", "_reader");
-    __PYX_ERR(0, 4332, __pyx_L1_error)
+    __PYX_ERR(0, 4352, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4331
+  /* "pywrapfst.pyx":4351
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -43868,7 +43514,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4331, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4351, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43885,7 +43531,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4334
+/* "pywrapfst.pyx":4354
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -43909,7 +43555,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4334, __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, 4354, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_19find)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -43924,13 +43570,13 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
         }
       }
       if (!__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4334, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
       } else {
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4334, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -43938,25 +43584,25 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_key};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4334, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4334, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4354, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_5);
           __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
           __Pyx_INCREF(__pyx_v_key);
           __Pyx_GIVEREF(__pyx_v_key);
           PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_key);
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4334, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
         }
       }
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_6 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4334, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_6 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4354, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __pyx_r = __pyx_t_6;
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -43965,7 +43611,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4350
+  /* "pywrapfst.pyx":4367
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
@@ -43974,13 +43620,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 '%s'", "_reader");
-    __PYX_ERR(0, 4350, __pyx_L1_error)
+    __PYX_ERR(0, 4367, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4350, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4367, __pyx_L1_error)
   __pyx_r = __pyx_v_self->_reader.get()->Find(__pyx_t_7);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4334
+  /* "pywrapfst.pyx":4354
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -44004,7 +43650,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_19find(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_18find[] = "\n    find(self, key)\n\n    Sets the current position to the first entry greater than or equal to the\n    key (a string) and indicates whether or not a match was found.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      key: A string key.\n\n    Returns:\n      True if the key was found, False otherwise.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_18find[] = "\n    find(self, key)\n\n    Sets the current position to the first entry greater than or equal to the\n    key (a string) and indicates whether or not a match was found.\n\n    Args:\n      key: A string key.\n\n    Returns:\n      True if the key was found, False otherwise.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_19find(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -44022,7 +43668,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18find(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4334, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44039,7 +43685,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4352
+/* "pywrapfst.pyx":4369
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -44061,7 +43707,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4352, __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, 4369, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_21get_fst)) {
       __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -44077,14 +43723,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4352, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4369, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4352, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4369, __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, 4352, __pyx_L1_error)
+      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__Fst))))) __PYX_ERR(0, 4369, __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;
@@ -44093,7 +43739,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4365
+  /* "pywrapfst.pyx":4379
  *     """
  *     cdef fst.FstClass *tfst = new fst.FstClass(
  *         deref(self._reader.get().GetFstClass()))             # <<<<<<<<<<<<<<
@@ -44102,10 +43748,10 @@ 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 '%s'", "_reader");
-    __PYX_ERR(0, 4365, __pyx_L1_error)
+    __PYX_ERR(0, 4379, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4364
+  /* "pywrapfst.pyx":4378
  *       A copy of the FST at the current position.
  *     """
  *     cdef fst.FstClass *tfst = new fst.FstClass(             # <<<<<<<<<<<<<<
@@ -44114,7 +43760,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  */
   __pyx_v_tfst = new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass()));
 
-  /* "pywrapfst.pyx":4366
+  /* "pywrapfst.pyx":4380
  *     cdef fst.FstClass *tfst = new fst.FstClass(
  *         deref(self._reader.get().GetFstClass()))
  *     return _init_XFst(tfst)             # <<<<<<<<<<<<<<
@@ -44122,13 +43768,13 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
  *   cpdef string get_key(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4366, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4380, __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":4352
+  /* "pywrapfst.pyx":4369
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -44152,7 +43798,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_21get_fst(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_20get_fst[] = "\n    get_fst(self)\n\n    Returns the FST at the current position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      A copy of the FST at the current position.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_20get_fst[] = "\n    get_fst(self)\n\n    Returns the FST at the current position.\n\n    Returns:\n      A copy of the FST at the current position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_21get_fst(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -44170,7 +43816,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20get_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, 4352, __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, 4369, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44187,7 +43833,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4368
+/* "pywrapfst.pyx":4382
  *     return _init_XFst(tfst)
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44209,7 +43855,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4368, __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, 4382, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_23get_key)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -44224,14 +43870,14 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4368, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4382, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4368, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4382, __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, 4368, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4382, __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;
@@ -44240,7 +43886,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4380
+  /* "pywrapfst.pyx":4391
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -44249,12 +43895,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 '%s'", "_reader");
-    __PYX_ERR(0, 4380, __pyx_L1_error)
+    __PYX_ERR(0, 4391, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4368
+  /* "pywrapfst.pyx":4382
  *     return _init_XFst(tfst)
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -44276,7 +43922,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_23get_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_22get_key[] = "\n    get_key(self)\n\n    Returns the string key at the current position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Returns:\n      The string key at the current position.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_22get_key[] = "\n    get_key(self)\n\n    Returns the string key at the current position.\n\n    Returns:\n      The string key at the current position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_23get_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -44294,7 +43940,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22get_key(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("get_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4368, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4382, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44311,7 +43957,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4382
+/* "pywrapfst.pyx":4393
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44331,7 +43977,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4382, __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, 4393, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_25next)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -44346,10 +43992,10 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4382, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4393, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4382, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4393, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44360,8 +44006,8 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4391
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":4399
+ *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
  * 
@@ -44369,11 +44015,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 '%s'", "_reader");
-    __PYX_ERR(0, 4391, __pyx_L1_error)
+    __PYX_ERR(0, 4399, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4382
+  /* "pywrapfst.pyx":4393
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -44395,7 +44041,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_25next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_24next[] = "\n    next(self)\n\n    Advances the iterator.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_24next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_25next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -44413,7 +44059,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24next(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, 4382, __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, 4393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44430,7 +44076,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4393
+/* "pywrapfst.pyx":4401
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44450,7 +44096,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4393, __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, 4401, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_27reset)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -44465,10 +44111,10 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4393, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4401, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4393, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4401, __pyx_L1_error)
       }
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44479,8 +44125,8 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4402
- *     should use the Pythonic API.
+  /* "pywrapfst.pyx":4407
+ *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
  * 
@@ -44488,11 +44134,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 '%s'", "_reader");
-    __PYX_ERR(0, 4402, __pyx_L1_error)
+    __PYX_ERR(0, 4407, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4393
+  /* "pywrapfst.pyx":4401
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -44514,7 +44160,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_27reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarReader_26reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n    ";
+static char __pyx_doc_9pywrapfst_9FarReader_26reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_27reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -44532,7 +44178,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26reset(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, 4393, __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, 4401, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44549,7 +44195,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4405
+/* "pywrapfst.pyx":4410
  * 
  *   # Dictionary-like access by combining `find` and `get_fst`.
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44578,7 +44224,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__getitem__(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4406
+  /* "pywrapfst.pyx":4411
  *   # Dictionary-like access by combining `find` and `get_fst`.
  *   def __getitem__(self, key):
  *     if not self.find(key):             # <<<<<<<<<<<<<<
@@ -44587,31 +44233,31 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__getitem__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "find");
-    __PYX_ERR(0, 4406, __pyx_L1_error)
+    __PYX_ERR(0, 4411, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->find(__pyx_v_self, __pyx_v_key, 0) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":4407
+    /* "pywrapfst.pyx":4412
  *   def __getitem__(self, key):
  *     if not self.find(key):
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
  *     return self.get_fst()
  * 
  */
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4407, __pyx_L1_error)
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4412, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_INCREF(__pyx_v_key);
     __Pyx_GIVEREF(__pyx_v_key);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_key);
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4407, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4412, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 4407, __pyx_L1_error)
+    __PYX_ERR(0, 4412, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4406
+    /* "pywrapfst.pyx":4411
  *   # Dictionary-like access by combining `find` and `get_fst`.
  *   def __getitem__(self, key):
  *     if not self.find(key):             # <<<<<<<<<<<<<<
@@ -44620,7 +44266,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4408
+  /* "pywrapfst.pyx":4413
  *     if not self.find(key):
  *       raise KeyError(key)
  *     return self.get_fst()             # <<<<<<<<<<<<<<
@@ -44630,15 +44276,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__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 '%s'", "get_fst");
-    __PYX_ERR(0, 4408, __pyx_L1_error)
+    __PYX_ERR(0, 4413, __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, 4408, __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, 4413, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4405
+  /* "pywrapfst.pyx":4410
  * 
  *   # Dictionary-like access by combining `find` and `get_fst`.
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -44658,7 +44304,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__getitem__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4431
+/* "pywrapfst.pyx":4436
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44694,28 +44340,28 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4432
+  /* "pywrapfst.pyx":4437
  * 
  *   def __init__(self):
  *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  */
-  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4437, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4433
+  /* "pywrapfst.pyx":4438
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4433, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4438, __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, 4433, __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, 4438, __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, 4433, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4438, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -44729,14 +44375,14 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
     }
   }
   if (!__pyx_t_5) {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4433, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4438, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_GOTREF(__pyx_t_3);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4433, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4438, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -44745,20 +44391,20 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
       PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_6};
-      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4433, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4438, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4433, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4438, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
       __Pyx_GIVEREF(__pyx_t_6);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
       __pyx_t_6 = 0;
-      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4433, __pyx_L1_error)
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4438, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -44775,14 +44421,14 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
     }
   }
   if (!__pyx_t_4) {
-    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44791,20 +44437,20 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4432, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4437, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4437, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -44812,9 +44458,9 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4432, __pyx_L1_error)
+  __PYX_ERR(0, 4437, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4431
+  /* "pywrapfst.pyx":4436
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -44837,7 +44483,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4435
+/* "pywrapfst.pyx":4440
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44870,7 +44516,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4436
+  /* "pywrapfst.pyx":4441
  * 
  *   def __repr__(self):
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -44878,20 +44524,20 @@ 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_s_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4436, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4441, __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 '%s'", "far_type");
-    __PYX_ERR(0, 4436, __pyx_L1_error)
+    __PYX_ERR(0, 4441, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyBytes_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, 4436, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyBytes_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, 4441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4436, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
   PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_self));
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4436, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -44909,7 +44555,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_4, __pyx_t_3, __pyx_t_5};
-    __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, 4436, __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, 4441, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44919,7 +44565,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_4, __pyx_t_3, __pyx_t_5};
-    __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, 4436, __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, 4441, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -44927,7 +44573,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, 4436, __pyx_L1_error)
+    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4441, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     if (__pyx_t_4) {
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -44938,7 +44584,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_5);
     __pyx_t_3 = 0;
     __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4436, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4441, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   }
@@ -44947,7 +44593,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4435
+  /* "pywrapfst.pyx":4440
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44971,7 +44617,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4439
+/* "pywrapfst.pyx":4444
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -45021,7 +44667,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, 4439, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4444, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -45038,7 +44684,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, 4439, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4444, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -45068,27 +44714,27 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_9 = NULL;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4460
+  /* "pywrapfst.pyx":4465
  *       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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4460, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4465, __pyx_L1_error)
   __pyx_v_ft = fst::script::GetFarType(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4462
+  /* "pywrapfst.pyx":4467
  *     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, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4462, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4462, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_filename, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4467, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4467, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4461
+  /* "pywrapfst.pyx":4466
  *     """
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
@@ -45097,7 +44743,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":4463
+  /* "pywrapfst.pyx":4468
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -45107,16 +44753,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_t_3 = ((__pyx_v_tfar == NULL) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4464
+    /* "pywrapfst.pyx":4469
  *         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_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4464, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4469, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4464, __pyx_L1_error)
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4469, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -45129,13 +44775,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
       }
     }
     if (!__pyx_t_8) {
-      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filename); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4464, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_filename); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4469, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_7)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_filename};
-        __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_6);
       } else
@@ -45143,19 +44789,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
         PyObject *__pyx_temp[2] = {__pyx_t_8, __pyx_v_filename};
-        __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
         __Pyx_GOTREF(__pyx_t_6);
       } else
       #endif
       {
-        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __pyx_t_8 = NULL;
         __Pyx_INCREF(__pyx_v_filename);
         __Pyx_GIVEREF(__pyx_v_filename);
         PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_filename);
-        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
@@ -45172,14 +44818,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
       }
     }
     if (!__pyx_t_7) {
-      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
+      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4469, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       __Pyx_GOTREF(__pyx_t_4);
     } else {
       #if CYTHON_FAST_PYCALL
       if (PyFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -45188,20 +44834,20 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
       #if CYTHON_FAST_PYCCALL
       if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
         PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
-        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else
       #endif
       {
-        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
         __Pyx_GIVEREF(__pyx_t_6);
         PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
         __pyx_t_6 = 0;
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4464, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4469, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       }
@@ -45209,9 +44855,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     __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, 4464, __pyx_L1_error)
+    __PYX_ERR(0, 4469, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4463
+    /* "pywrapfst.pyx":4468
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(filename), tostring(arc_type), ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -45220,20 +44866,20 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   }
 
-  /* "pywrapfst.pyx":4465
+  /* "pywrapfst.pyx":4470
  *     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 = __pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4465, __pyx_L1_error)
+  __pyx_t_4 = __pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4470, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (!(likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst_FarWriter)))) __PYX_ERR(0, 4465, __pyx_L1_error)
+  if (!(likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_9pywrapfst_FarWriter)))) __PYX_ERR(0, 4470, __pyx_L1_error)
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_4);
   __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":4466
+  /* "pywrapfst.pyx":4471
  *       raise FstIOError("Open failed: {!r}".format(filename))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)             # <<<<<<<<<<<<<<
@@ -45242,11 +44888,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 '%s'", "_writer");
-    __PYX_ERR(0, 4466, __pyx_L1_error)
+    __PYX_ERR(0, 4471, __pyx_L1_error)
   }
   __pyx_v_result->_writer.reset(__pyx_v_tfar);
 
-  /* "pywrapfst.pyx":4467
+  /* "pywrapfst.pyx":4472
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  *     return result             # <<<<<<<<<<<<<<
@@ -45258,7 +44904,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4439
+  /* "pywrapfst.pyx":4444
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -45283,7 +44929,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4471
+/* "pywrapfst.pyx":4476
  *   # NB: Invoking this method is DANGEROUS: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void _close(self):             # <<<<<<<<<<<<<<
@@ -45295,7 +44941,7 @@ static void __pyx_f_9pywrapfst_9FarWriter__close(struct __pyx_obj_9pywrapfst_Far
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_close", 0);
 
-  /* "pywrapfst.pyx":4472
+  /* "pywrapfst.pyx":4477
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void _close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
@@ -45304,11 +44950,11 @@ static void __pyx_f_9pywrapfst_9FarWriter__close(struct __pyx_obj_9pywrapfst_Far
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_writer");
-    __PYX_ERR(0, 4472, __pyx_L1_error)
+    __PYX_ERR(0, 4477, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4471
+  /* "pywrapfst.pyx":4476
  *   # NB: Invoking this method is DANGEROUS: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void _close(self):             # <<<<<<<<<<<<<<
@@ -45324,7 +44970,7 @@ static void __pyx_f_9pywrapfst_9FarWriter__close(struct __pyx_obj_9pywrapfst_Far
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4474
+/* "pywrapfst.pyx":4479
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45348,7 +44994,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4474, __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, 4479, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_7add)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -45367,7 +45013,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, 4474, __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, 4479, __pyx_L1_error)
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_GOTREF(__pyx_t_2);
       } else
@@ -45375,13 +45021,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, 4474, __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, 4479, __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, 4474, __pyx_L1_error)
+        __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4479, __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;
@@ -45392,7 +45038,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, 4474, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4479, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       }
@@ -45404,7 +45050,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4496
+  /* "pywrapfst.pyx":4498
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45413,33 +45059,33 @@ 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 '%s'", "_writer");
-    __PYX_ERR(0, 4496, __pyx_L1_error)
+    __PYX_ERR(0, 4498, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4496, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4498, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_fst");
-    __PYX_ERR(0, 4496, __pyx_L1_error)
+    __PYX_ERR(0, 4498, __pyx_L1_error)
   }
   __pyx_t_8 = ((!(__pyx_v_self->_writer.get()->Add(__pyx_t_7, (*__pyx_v_ifst->_fst)) != 0)) != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":4497
+    /* "pywrapfst.pyx":4499
  *     # 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_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4497, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstOpError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4499, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__62, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4497, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__66, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4499, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 4497, __pyx_L1_error)
+    __PYX_ERR(0, 4499, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4496
+    /* "pywrapfst.pyx":4498
  *     # 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)):             # <<<<<<<<<<<<<<
@@ -45448,7 +45094,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4499
+  /* "pywrapfst.pyx":4501
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45457,28 +45103,28 @@ 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 '%s'", "_writer");
-    __PYX_ERR(0, 4499, __pyx_L1_error)
+    __PYX_ERR(0, 4501, __pyx_L1_error)
   }
   __pyx_t_8 = (__pyx_v_self->_writer.get()->Error() != 0);
   if (__pyx_t_8) {
 
-    /* "pywrapfst.pyx":4500
+    /* "pywrapfst.pyx":4502
  *     # 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_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4500, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4502, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__63, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4500, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__67, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4502, __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, 4500, __pyx_L1_error)
+    __PYX_ERR(0, 4502, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4499
+    /* "pywrapfst.pyx":4501
  *       raise FstOpError("Incompatible or invalid arc type")
  *     # An error here usually indicates a key out of order.
  *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
@@ -45487,7 +45133,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4474
+  /* "pywrapfst.pyx":4479
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -45510,7 +45156,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarWriter_6add[] = "\n    add(self, key, ifst)\n\n    Adds an FST to the FAR.\n\n    This method adds an FST to the FAR which can be retrieved with the\n    specified string key.\n\n    This method is provided for compatibility with the C++ API only; most users\n    should use the Pythonic API.\n\n    Args:\n      key: The string used to key the input FST.\n      ifst: The FST to write to the FAR.\n\n    Raises:\n      FstArgError: Key out of order.\n      FstOpError: Incompatible or invalid arc type.\n    ";
+static char __pyx_doc_9pywrapfst_9FarWriter_6add[] = "\n    add(self, key, ifst)\n\n    Adds an FST to the FAR.\n\n    This method adds an FST to the FAR which can be retrieved with the\n    specified string key.\n\n    Args:\n      key: The string used to key the input FST.\n      ifst: The FST to write to the FAR.\n\n    Raises:\n      FstArgError: Key out of order.\n      FstOpError: Incompatible or invalid arc type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_key = 0;
   struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
@@ -45537,11 +45183,11 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
         case  1:
         if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ifst)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4474, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4479, __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, 4474, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4479, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -45554,13 +45200,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, 4474, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4479, __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, 4474, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst__Fst, 1, "ifst", 0))) __PYX_ERR(0, 4479, __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 */
@@ -45578,8 +45224,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, 4474, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4474, __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, 4479, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4479, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45596,12 +45242,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4502
+/* "pywrapfst.pyx":4504
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._writer.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -45618,7 +45264,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4502, __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, 4504, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_9arc_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -45633,14 +45279,14 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4502, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4504, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4502, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4504, __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, 4502, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4504, __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;
@@ -45649,26 +45295,26 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4503
- * 
- *   cpdef string arc_type(self):
+  /* "pywrapfst.pyx":4510
+ *     Returns a string indicating the arc type.
+ *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
  * 
  *   cpdef bool error(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_writer");
-    __PYX_ERR(0, 4503, __pyx_L1_error)
+    __PYX_ERR(0, 4510, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4502
+  /* "pywrapfst.pyx":4504
  *       raise FstArgError("Key out of order")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
- *     return self._writer.get().ArcType()
- * 
+ *     """
+ *     arc_type(self)
  */
 
   /* function exit code */
@@ -45685,6 +45331,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_9FarWriter_8arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_9arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -45702,7 +45349,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_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4502, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4504, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45719,7 +45366,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4505
+/* "pywrapfst.pyx":4512
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45741,7 +45388,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4505, __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, 4512, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_11error)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -45756,14 +45403,14 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4505, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4512, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4505, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4512, __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, 4505, __pyx_L1_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4512, __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;
@@ -45772,7 +45419,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4514
+  /* "pywrapfst.pyx":4521
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -45781,12 +45428,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 '%s'", "_writer");
-    __PYX_ERR(0, 4514, __pyx_L1_error)
+    __PYX_ERR(0, 4521, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4505
+  /* "pywrapfst.pyx":4512
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -45827,7 +45474,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, 4505, __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, 4512, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45844,12 +45491,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4516
+/* "pywrapfst.pyx":4523
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
- *     return fst.GetFarTypeString(self._writer.get().Type())
- * 
+ *     """
+ *     far_type(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_13far_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
@@ -45866,7 +45513,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
   else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4516, __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, 4523, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_13far_type)) {
       __Pyx_INCREF(__pyx_t_1);
@@ -45881,14 +45528,14 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
         }
       }
       if (__pyx_t_4) {
-        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4516, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4523, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       } else {
-        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4516, __pyx_L1_error)
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4523, __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, 4516, __pyx_L1_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4523, __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;
@@ -45897,26 +45544,26 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   }
 
-  /* "pywrapfst.pyx":4517
- * 
- *   cpdef string far_type(self):
+  /* "pywrapfst.pyx":4529
+ *     Returns a string indicating the FAR type.
+ *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
  * 
  *   # Dictionary-like assignment.
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "_writer");
-    __PYX_ERR(0, 4517, __pyx_L1_error)
+    __PYX_ERR(0, 4529, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4516
+  /* "pywrapfst.pyx":4523
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
- *     return fst.GetFarTypeString(self._writer.get().Type())
- * 
+ *     """
+ *     far_type(self)
  */
 
   /* function exit code */
@@ -45933,6 +45580,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_13far_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_9FarWriter_12far_type[] = "\n    far_type(self)\n\n    Returns a string indicating the FAR type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_13far_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -45950,7 +45598,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_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4516, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4523, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45967,7 +45615,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4520
+/* "pywrapfst.pyx":4532
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -45981,7 +45629,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, 4520, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst__Fst, 1, "fst", 0))) __PYX_ERR(0, 4532, __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 */
@@ -45998,7 +45646,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4521
+  /* "pywrapfst.pyx":4533
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
@@ -46007,11 +45655,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 '%s'", "add");
-    __PYX_ERR(0, 4521, __pyx_L1_error)
+    __PYX_ERR(0, 4533, __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, 4521, __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, 4533, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4520
+  /* "pywrapfst.pyx":4532
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
@@ -46030,7 +45678,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4536
+/* "pywrapfst.pyx":4548
  * 
  * @atexit.register
  * def _reset_fst_error_fatal():             # <<<<<<<<<<<<<<
@@ -46059,19 +45707,19 @@ static PyObject *__pyx_pf_9pywrapfst_56_reset_fst_error_fatal(CYTHON_UNUSED PyOb
   bool __pyx_t_2;
   __Pyx_RefNannySetupContext("_reset_fst_error_fatal", 0);
 
-  /* "pywrapfst.pyx":4537
+  /* "pywrapfst.pyx":4549
  * @atexit.register
  * def _reset_fst_error_fatal():
  *   fst.FLAGS_fst_error_fatal = _fst_error_fatal_old             # <<<<<<<<<<<<<<
  * 
  */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_fst_error_fatal_old); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4537, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_fst_error_fatal_old); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4549, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4537, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4549, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   FLAGS_fst_error_fatal = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4536
+  /* "pywrapfst.pyx":4548
  * 
  * @atexit.register
  * def _reset_fst_error_fatal():             # <<<<<<<<<<<<<<
@@ -46647,7 +46295,7 @@ static PyMethodDef __pyx_methods_9pywrapfst_Weight[] = {
   {"One", (PyCFunction)__pyx_pw_9pywrapfst_6Weight_13One, METH_O, __pyx_doc_9pywrapfst_6Weight_12One},
   {"NoWeight", (PyCFunction)__pyx_pw_9pywrapfst_6Weight_15NoWeight, METH_O, __pyx_doc_9pywrapfst_6Weight_14NoWeight},
   {"to_string", (PyCFunction)__pyx_pw_9pywrapfst_6Weight_19to_string, METH_NOARGS, 0},
-  {"type", (PyCFunction)__pyx_pw_9pywrapfst_6Weight_21type, METH_NOARGS, 0},
+  {"type", (PyCFunction)__pyx_pw_9pywrapfst_6Weight_21type, METH_NOARGS, __pyx_doc_9pywrapfst_6Weight_20type},
   {0, 0, 0, 0}
 };
 
@@ -46739,7 +46387,7 @@ static PyTypeObject __pyx_type_9pywrapfst_Weight = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  Weight(weight_type, weight_string)\n\n  FST weight class.\n\n  This class represents an FST weight. When passed as an argument to an FST\n  operation, it should have the weight type of the input FST(s) to said\n  operation.\n\n  Args:\n    weight_type: A string indicating the weight type.\n    weight_string: A string indicating the underlying weight.\n\n  Raises:\n    FstBadWeightError: invalid weight.\n    FstUnknownWeightTypeError: weight type not found.\n  ", /*tp_doc*/
+  "\n  Weight(weight_type, weight_string)\n\n  FST weight class.\n\n  This class represents an FST weight. When passed as an argument to an FST\n  operation, it should have the weight type of the input FST(s) to said\n  operation.\n\n  Args:\n    weight_type: A string indicating the weight type.\n    weight_string: A string indicating the underlying weight.\n\n  Raises:\n    FstArgError: Weight type not found.\n    FstBadWeightError: Invalid weight.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   __pyx_pw_9pywrapfst_6Weight_17__richcmp__, /*tp_richcompare*/
@@ -46796,15 +46444,15 @@ static void __pyx_tp_dealloc_9pywrapfst__SymbolTable(PyObject *o) {
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst__SymbolTable[] = {
-  {"available_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_5available_key, METH_NOARGS, 0},
-  {"checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_7checksum, METH_NOARGS, 0},
+  {"available_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_5available_key, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_4available_key},
+  {"checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_7checksum, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_6checksum},
   {"copy", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_9copy, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_8copy},
   {"find", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_11find, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_10find},
-  {"member", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_13member, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_12member},
-  {"get_nth_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_17get_nth_key, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_16get_nth_key},
-  {"labeled_checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_19labeled_checksum, METH_NOARGS, 0},
-  {"name", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_21name, METH_NOARGS, 0},
-  {"num_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols, METH_NOARGS, 0},
+  {"get_nth_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_13get_nth_key, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_12get_nth_key},
+  {"labeled_checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_15labeled_checksum, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_14labeled_checksum},
+  {"member", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_17member, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_16member},
+  {"name", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_21name, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_20name},
+  {"num_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_23num_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_22num_symbols},
   {"write", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_25write, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_24write},
   {"write_text", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_27write_text, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_26write_text},
   {0, 0, 0, 0}
@@ -46818,7 +46466,7 @@ static PySequenceMethods __pyx_tp_as_sequence__SymbolTable = {
   0, /*sq_slice*/
   0, /*sq_ass_item*/
   0, /*sq_ass_slice*/
-  __pyx_pw_9pywrapfst_12_SymbolTable_15__contains__, /*sq_contains*/
+  __pyx_pw_9pywrapfst_12_SymbolTable_19__contains__, /*sq_contains*/
   0, /*sq_inplace_concat*/
   0, /*sq_inplace_repeat*/
 };
@@ -47200,7 +46848,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  (No constructor.)\n\n  Mutable SymbolTable assigned to an FST.\n\n  Attributes:\n    available_key: An integer indicating the next available key index in the\n        table.\n    checksum: A string indicating the label-agnostic MD5 checksum for the table.\n    labeled_checksum: A string indicating the label-dependent MD5 checksum for\n        the table.\n    name: A string indicating the table's name.\n    num_symbols: An integer indicating the number of symbols in the table.\n  ", /*tp_doc*/
+  "\n  (No constructor.)\n\n  Mutable SymbolTable assigned to an FST.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -47295,7 +46943,7 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTable = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  SymbolTable(name=\"<unspecified>\")\n\n  Mutable SymbolTable class.\n\n  This class wraps the library SymbolTable and exposes both const (i.e.,\n  access) and non-const (i.e., mutation) methods of wrapped object. Unlike\n  other classes in the hierarchy, it has a working constructor and can be used\n  to programmatically construct a SymbolTable in memory.\n\n  Args:\n    name: A string indicating the table's name\n\n  Attributes:\n    available_key: An integer indicating the next available key index in the\n        table.\n    checksum: A string indicating the label-agnostic MD5 checksum for the table.\n    labeled_checksum: A string indicating the label-dependent MD5 checksum for\n        the table.\n    name: A string indicating the table's name.\n    num_symbols: An integer indicating the number of symbols in the table.\n  ", /*tp_doc*/
+  "\n  SymbolTable(name=\"<unspecified>\")\n\n  Mutable SymbolTable class.\n\n  This class wraps the library SymbolTable and exposes both const (i.e.,\n  access) and non-const (i.e., mutation) methods of wrapped object.\n\n  Unlike other classes in the hierarchy, it has a working constructor and can be\n  used to programmatically construct a SymbolTable in memory.\n\n  Args:\n    name: An optional string indicating the table's name.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -47396,7 +47044,7 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  SymbolTableIterator(syms)\n\n  This class is used for iterating over a symbol table using a Pythonic API. It\n  also supports the C++ API methods, but most users should simply place a\n  SymbolTable in an iteration context and take advantage of the Pythonic API\n  that provides.\n  ", /*tp_doc*/
+  "\n  SymbolTableIterator(syms)\n\n  This class is used for iterating over a symbol table.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -47456,14 +47104,14 @@ static void __pyx_tp_dealloc_9pywrapfst_EncodeMapper(PyObject *o) {
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst_EncodeMapper[] = {
-  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type, METH_NOARGS, 0},
-  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_9flags, METH_NOARGS, 0},
-  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols, METH_NOARGS, 0},
-  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_5arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_4arc_type},
+  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_9flags, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_8flags},
+  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_11input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_10input_symbols},
+  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_13output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_12output_symbols},
   {"properties", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_15properties, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_14properties},
   {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_17set_input_symbols, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_16set_input_symbols},
   {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_19set_output_symbols, METH_O, __pyx_doc_9pywrapfst_12EncodeMapper_18set_output_symbols},
-  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type, METH_NOARGS, 0},
+  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_12EncodeMapper_21weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_12EncodeMapper_20weight_type},
   {0, 0, 0, 0}
 };
 
@@ -47554,25 +47202,25 @@ static void __pyx_tp_dealloc_9pywrapfst__Fst(PyObject *o) {
 
 static PyMethodDef __pyx_methods_9pywrapfst__Fst[] = {
   {"_repr_svg_", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst__repr_svg_},
-  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_9arc_type, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_9arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_8arc_type},
   {"arcs", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_11arcs, METH_O, __pyx_doc_9pywrapfst_4_Fst_10arcs},
   {"copy", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_13copy, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_12copy},
   {"draw", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_15draw, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_14draw},
   {"final", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_17final, METH_O, __pyx_doc_9pywrapfst_4_Fst_16final},
-  {"fst_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_19fst_type, METH_NOARGS, 0},
-  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_21input_symbols, METH_NOARGS, 0},
+  {"fst_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_19fst_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_18fst_type},
+  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_21input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_20input_symbols},
   {"num_arcs", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_23num_arcs, METH_O, __pyx_doc_9pywrapfst_4_Fst_22num_arcs},
   {"num_input_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_25num_input_epsilons, METH_O, __pyx_doc_9pywrapfst_4_Fst_24num_input_epsilons},
   {"num_output_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_27num_output_epsilons, METH_O, __pyx_doc_9pywrapfst_4_Fst_26num_output_epsilons},
-  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_29output_symbols, METH_NOARGS, 0},
+  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_29output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_28output_symbols},
   {"properties", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_31properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_30properties},
-  {"start", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_33start, METH_NOARGS, 0},
+  {"start", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_33start, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_32start},
   {"states", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_35states, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_34states},
   {"text", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_37text, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_36text},
   {"verify", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_39verify, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_38verify},
   {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_41weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_40weight_type},
   {"write", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_43write, METH_O, __pyx_doc_9pywrapfst_4_Fst_42write},
-  {"WriteToString", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_45WriteToString, METH_NOARGS, 0},
+  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_45write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_44write_to_string},
   {0, 0, 0, 0}
 };
 
@@ -47670,9 +47318,9 @@ static PyMethodDef __pyx_methods_9pywrapfst__MutableFst[] = {
   {"invert", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_21invert, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_20invert},
   {"minimize", (PyCFunction)__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, 0},
-  {"mutable_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_29mutable_output_symbols, METH_NOARGS, 0},
-  {"num_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_31num_states, METH_NOARGS, 0},
+  {"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)__pyx_pw_9pywrapfst_11_MutableFst_33project, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_32project},
   {"prune", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_35prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_34prune},
   {"push", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_37push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_36push},
@@ -47683,10 +47331,10 @@ static PyMethodDef __pyx_methods_9pywrapfst__MutableFst[] = {
   {"reweight", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_47reweight, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_46reweight},
   {"rmepsilon", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_49rmepsilon, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_48rmepsilon},
   {"set_final", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_51set_final, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_50set_final},
-  {"set_properties", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_53set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_52set_properties},
-  {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_55set_start, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_54set_start},
-  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_57set_input_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_56set_input_symbols},
-  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_59set_output_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_58set_output_symbols},
+  {"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)__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},
   {0, 0, 0, 0}
@@ -47984,7 +47632,7 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  ArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST.\n  It supports the full C++ API, but most users should just call the `arcs`\n  method of an FST object and take advantage of the Pythonic API.\n  ", /*tp_doc*/
+  "\n  ArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -48046,16 +47694,15 @@ static void __pyx_tp_dealloc_9pywrapfst_MutableArcIterator(PyObject *o) {
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst_MutableArcIterator[] = {
-  {"__next__", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
-  {"done", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_8done},
-  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_11flags, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_10flags},
-  {"next", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_13next, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_12next},
-  {"position", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_15position, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_14position},
-  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_17reset, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_16reset},
-  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_19seek, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_18seek},
-  {"set_flags", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_21set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_18MutableArcIterator_20set_flags},
-  {"set_value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_23set_value, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_22set_value},
-  {"value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_25value, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_24value},
+  {"done", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_5done, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_4done},
+  {"flags", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_7flags, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_6flags},
+  {"next", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_9next, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_8next},
+  {"position", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_11position, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_10position},
+  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_13reset, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_12reset},
+  {"seek", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_15seek, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_14seek},
+  {"set_flags", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_17set_flags, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_18MutableArcIterator_16set_flags},
+  {"set_value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_19set_value, METH_O, __pyx_doc_9pywrapfst_18MutableArcIterator_18set_value},
+  {"value", (PyCFunction)__pyx_pw_9pywrapfst_18MutableArcIterator_21value, METH_NOARGS, __pyx_doc_9pywrapfst_18MutableArcIterator_20value},
   {0, 0, 0, 0}
 };
 
@@ -48085,13 +47732,13 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  MutableArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST,\n  also permitting mutation of the current arc. It supports the full C++ API,\n  but most users should just call the `mutable_arcs` method of an FST object\n  and take advantage of the Pythonic API.\n  ", /*tp_doc*/
+  "\n  MutableArcIterator(ifst, state)\n\n  This class is used for iterating over the arcs leaving some state of an FST,\n  also permitting mutation of the current arc.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_18MutableArcIterator_5__iter__, /*tp_iter*/
-  __pyx_pw_9pywrapfst_18MutableArcIterator_7__next__, /*tp_iternext*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
   __pyx_methods_9pywrapfst_MutableArcIterator, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
@@ -48181,7 +47828,7 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  StateIterator(ifst)\n\n  This class is used for iterating over the states in an FST. It supports the\n  full C++ API, but most users should just place an FST argument in an\n  iteration context and take advantage of the Pythonic API.\n  ", /*tp_doc*/
+  "\n  StateIterator(ifst)\n\n  This class is used for iterating over the states in an FST.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -48349,7 +47996,7 @@ static PyObject *__pyx_sq_item_9pywrapfst_FarReader(PyObject *o, Py_ssize_t i) {
 static PyMethodDef __pyx_methods_9pywrapfst_FarReader[] = {
   {"open", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_5open, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_9FarReader_4open},
   {"__next__", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_9__next__, METH_NOARGS|METH_COEXIST, 0},
-  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_11arc_type, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_11arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_10arc_type},
   {"done", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_13done, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_12done},
   {"error", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_15error, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_14error},
   {"far_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_17far_type, METH_NOARGS, 0},
@@ -48406,7 +48053,7 @@ static PyTypeObject __pyx_type_9pywrapfst_FarReader = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  (No constructor.)\n\n  FAR (\"Fst ARchive\") reader object.\n\n  This class is used to read a FAR from disk. FARs contain one or more FSTs (of\n  the same arc type) indexed by a unique string key. To construct a FarReader\n  object, use the `open` class method. FSTs can be accessed from a FAR using the\n  familiar C++ API methods, but a user who wishes to access all FSTs in random\n  order should simply place a FarReader in an iteration context and take\n  advantage of the Pythonic API that provides.\n\n  Attributes:\n    arc_type: A string indicating the arc type.\n    far_type: A string indicating the FAR type.\n  ", /*tp_doc*/
+  "\n  (No constructor.)\n\n  FAR (\"Fst ARchive\") reader object.\n\n  This class is used to read a FAR from disk. FARs contain one or more FSTs (of\n  the same arc type) indexed by a unique string key. To construct a FarReader\n  object, use the `open` class method.\n\n  Attributes:\n    arc_type: A string indicating the arc type.\n    far_type: A string indicating the FAR type.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -48479,9 +48126,9 @@ static int __pyx_mp_ass_subscript_9pywrapfst_FarWriter(PyObject *o, PyObject *i,
 static PyMethodDef __pyx_methods_9pywrapfst_FarWriter[] = {
   {"create", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_5create, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_9FarWriter_4create},
   {"add", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_7add, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_9FarWriter_6add},
-  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_9arc_type, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_9arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_9FarWriter_8arc_type},
   {"error", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_11error, METH_NOARGS, __pyx_doc_9pywrapfst_9FarWriter_10error},
-  {"far_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_13far_type, METH_NOARGS, 0},
+  {"far_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarWriter_13far_type, METH_NOARGS, __pyx_doc_9pywrapfst_9FarWriter_12far_type},
   {0, 0, 0, 0}
 };
 
@@ -48595,14 +48242,20 @@ static struct PyModuleDef __pyx_moduledef = {
 #endif
 
 static __Pyx_StringTabEntry __pyx_string_tab[] = {
-  {&__pyx_kp_b_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 0, 0},
   {&__pyx_n_s_ACCEPTOR, __pyx_k_ACCEPTOR, sizeof(__pyx_k_ACCEPTOR), 0, 0, 1, 1},
   {&__pyx_n_s_ACCESSIBLE, __pyx_k_ACCESSIBLE, sizeof(__pyx_k_ACCESSIBLE), 0, 0, 1, 1},
   {&__pyx_n_s_ACYCLIC, __pyx_k_ACYCLIC, sizeof(__pyx_k_ACYCLIC), 0, 0, 1, 1},
   {&__pyx_n_s_ADD_ARC_PROPERTIES, __pyx_k_ADD_ARC_PROPERTIES, sizeof(__pyx_k_ADD_ARC_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_ADD_STATE_PROPERTIES, __pyx_k_ADD_STATE_PROPERTIES, sizeof(__pyx_k_ADD_STATE_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_k_ADD_SUPERFINAL_PROPERTIES, sizeof(__pyx_k_ADD_SUPERFINAL_PROPERTIES), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_FLAGS, __pyx_k_ARC_FLAGS, sizeof(__pyx_k_ARC_FLAGS), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_I_LABEL_VALUE, __pyx_k_ARC_I_LABEL_VALUE, sizeof(__pyx_k_ARC_I_LABEL_VALUE), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_k_ARC_NEXT_STATE_VALUE, sizeof(__pyx_k_ARC_NEXT_STATE_VALUE), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_NO_CACHE, __pyx_k_ARC_NO_CACHE, sizeof(__pyx_k_ARC_NO_CACHE), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_O_LABEL_VALUE, __pyx_k_ARC_O_LABEL_VALUE, sizeof(__pyx_k_ARC_O_LABEL_VALUE), 0, 0, 1, 1},
   {&__pyx_n_s_ARC_SORT_PROPERTIES, __pyx_k_ARC_SORT_PROPERTIES, sizeof(__pyx_k_ARC_SORT_PROPERTIES), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_VALUE_FLAGS, __pyx_k_ARC_VALUE_FLAGS, sizeof(__pyx_k_ARC_VALUE_FLAGS), 0, 0, 1, 1},
+  {&__pyx_n_s_ARC_WEIGHT_VALUE, __pyx_k_ARC_WEIGHT_VALUE, sizeof(__pyx_k_ARC_WEIGHT_VALUE), 0, 0, 1, 1},
   {&__pyx_kp_s_ArcIterator_at_0x_x, __pyx_k_ArcIterator_at_0x_x, sizeof(__pyx_k_ArcIterator_at_0x_x), 0, 0, 1, 0},
   {&__pyx_kp_s_Arc_at_0x_x, __pyx_k_Arc_at_0x_x, sizeof(__pyx_k_Arc_at_0x_x), 0, 0, 1, 0},
   {&__pyx_n_s_BINARY_PROPERTIES, __pyx_k_BINARY_PROPERTIES, sizeof(__pyx_k_BINARY_PROPERTIES), 0, 0, 1, 1},
@@ -48619,6 +48272,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_k_DELETE_ARC_PROPERTIES, sizeof(__pyx_k_DELETE_ARC_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_k_DELETE_STATE_PROPERTIES, sizeof(__pyx_k_DELETE_STATE_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_DOT_TSVG, __pyx_k_DOT_TSVG, sizeof(__pyx_k_DOT_TSVG), 0, 0, 1, 1},
+  {&__pyx_n_s_ENCODE_FLAGS, __pyx_k_ENCODE_FLAGS, sizeof(__pyx_k_ENCODE_FLAGS), 0, 0, 1, 1},
+  {&__pyx_n_s_ENCODE_LABELS, __pyx_k_ENCODE_LABELS, sizeof(__pyx_k_ENCODE_LABELS), 0, 0, 1, 1},
+  {&__pyx_n_s_ENCODE_WEIGHTS, __pyx_k_ENCODE_WEIGHTS, sizeof(__pyx_k_ENCODE_WEIGHTS), 0, 0, 1, 1},
   {&__pyx_n_s_EPSILONS, __pyx_k_EPSILONS, sizeof(__pyx_k_EPSILONS), 0, 0, 1, 1},
   {&__pyx_n_s_ERROR, __pyx_k_ERROR, sizeof(__pyx_k_ERROR), 0, 0, 1, 1},
   {&__pyx_n_s_EXPANDED, __pyx_k_EXPANDED, sizeof(__pyx_k_EXPANDED), 0, 0, 1, 1},
@@ -48636,7 +48292,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_FstIOError, __pyx_k_FstIOError, sizeof(__pyx_k_FstIOError), 0, 0, 1, 1},
   {&__pyx_n_s_FstIndexError, __pyx_k_FstIndexError, sizeof(__pyx_k_FstIndexError), 0, 0, 1, 1},
   {&__pyx_n_s_FstOpError, __pyx_k_FstOpError, sizeof(__pyx_k_FstOpError), 0, 0, 1, 1},
-  {&__pyx_n_s_FstUnknownWeightTypeError, __pyx_k_FstUnknownWeightTypeError, sizeof(__pyx_k_FstUnknownWeightTypeError), 0, 0, 1, 1},
   {&__pyx_kp_s_Fst_SymbolTable_r_at_0x_x, __pyx_k_Fst_SymbolTable_r_at_0x_x, sizeof(__pyx_k_Fst_SymbolTable_r_at_0x_x), 0, 0, 1, 0},
   {&__pyx_n_s_Fst___new, __pyx_k_Fst___new, sizeof(__pyx_k_Fst___new), 0, 0, 1, 1},
   {&__pyx_kp_s_Fst_arc_type_standard_Construct, __pyx_k_Fst_arc_type_standard_Construct, sizeof(__pyx_k_Fst_arc_type_standard_Construct), 0, 0, 1, 0},
@@ -48656,6 +48311,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_s_Incompatible_or_invalid_weight_t, __pyx_k_Incompatible_or_invalid_weight_t, sizeof(__pyx_k_Incompatible_or_invalid_weight_t), 0, 0, 1, 0},
   {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
   {&__pyx_kp_s_Invalid_operator_r, __pyx_k_Invalid_operator_r, sizeof(__pyx_k_Invalid_operator_r), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_weight, __pyx_k_Invalid_weight, sizeof(__pyx_k_Invalid_weight), 0, 0, 1, 0},
   {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1},
   {&__pyx_kp_s_Key_out_of_order, __pyx_k_Key_out_of_order, sizeof(__pyx_k_Key_out_of_order), 0, 0, 1, 0},
   {&__pyx_n_s_MUTABLE, __pyx_k_MUTABLE, sizeof(__pyx_k_MUTABLE), 0, 0, 1, 1},
@@ -48721,9 +48377,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_WEIGHTED_CYCLES, __pyx_k_WEIGHTED_CYCLES, sizeof(__pyx_k_WEIGHTED_CYCLES), 0, 0, 1, 1},
   {&__pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_k_WEIGHT_INVARIANT_PROPERTIES, sizeof(__pyx_k_WEIGHT_INVARIANT_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_kp_s_Weight_at_0x_x, __pyx_k_Weight_at_0x_x, sizeof(__pyx_k_Weight_at_0x_x), 0, 0, 1, 0},
-  {&__pyx_n_s_WriteToString, __pyx_k_WriteToString, sizeof(__pyx_k_WriteToString), 0, 0, 1, 1},
+  {&__pyx_kp_s_Weight_type_not_found, __pyx_k_Weight_type_not_found, sizeof(__pyx_k_Weight_type_not_found), 0, 0, 1, 0},
   {&__pyx_kp_s_Write_failed_r, __pyx_k_Write_failed_r, sizeof(__pyx_k_Write_failed_r), 0, 0, 1, 0},
   {&__pyx_n_s_Zero, __pyx_k_Zero, sizeof(__pyx_k_Zero), 0, 0, 1, 1},
+  {&__pyx_kp_b__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 0, 0, 0},
   {&__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},
@@ -48931,6 +48588,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_width, __pyx_k_width, sizeof(__pyx_k_width), 0, 0, 1, 1},
   {&__pyx_n_s_write, __pyx_k_write, sizeof(__pyx_k_write), 0, 0, 1, 1},
   {&__pyx_n_s_write_text, __pyx_k_write_text, sizeof(__pyx_k_write_text), 0, 0, 1, 1},
+  {&__pyx_n_s_write_to_string, __pyx_k_write_to_string, sizeof(__pyx_k_write_to_string), 0, 0, 1, 1},
   {0, 0, 0, 0, 0, 0, 0}
 };
 static int __Pyx_InitCachedBuiltins(void) {
@@ -48938,12 +48596,12 @@ static int __Pyx_InitCachedBuiltins(void) {
   __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 131, __pyx_L1_error)
   __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 136, __pyx_L1_error)
   __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 141, __pyx_L1_error)
-  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2671, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 2691, __pyx_L1_error)
-  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 370, __pyx_L1_error)
-  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 434, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 726, __pyx_L1_error)
-  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1145, __pyx_L1_error)
+  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2747, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 2767, __pyx_L1_error)
+  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 365, __pyx_L1_error)
+  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 435, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 741, __pyx_L1_error)
+  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1156, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -48953,394 +48611,438 @@ static int __Pyx_InitCachedConstants(void) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
 
-  /* "pywrapfst.pyx":1390
+  /* "pywrapfst.pyx":383
+ *   cdef void _check_weight(self) except *:
+ *     if self.type() == b"none":
+ *       raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
+ *     if self.to_string() == b"BadNumber":
+ *       raise FstBadWeightError("Invalid weight")
+ */
+  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Weight_type_not_found); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 383, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple_);
+  __Pyx_GIVEREF(__pyx_tuple_);
+
+  /* "pywrapfst.pyx":385
+ *       raise FstArgError("Weight type not found")
+ *     if self.to_string() == b"BadNumber":
+ *       raise FstBadWeightError("Invalid weight")             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef Weight copy(self):
+ */
+  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_Invalid_weight); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 385, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__2);
+  __Pyx_GIVEREF(__pyx_tuple__2);
+
+  /* "pywrapfst.pyx":637
+ *       tostring(weight_type))))
+ *   if result._weight.get().Type() == b"none":
+ *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
+ *   return result
+ * 
+ */
+  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Weight_type_not_found); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 637, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__3);
+  __Pyx_GIVEREF(__pyx_tuple__3);
+
+  /* "pywrapfst.pyx":646
+ *         fst.WeightClass.One(tostring(weight_type))))
+ *   if result._weight.get().Type() == b"none":
+ *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
+ *   return result
+ * 
+ */
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_Weight_type_not_found); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 646, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "pywrapfst.pyx":1411
  *     if proc.returncode != 0:  # Just to be explicit.
  *       raise subprocess.CalledProcessError(proc.returncode, self._DOT_TSVG)
  *     return sout.decode("utf8")             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_n_s_utf8); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 1390, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__2);
-  __Pyx_GIVEREF(__pyx_tuple__2);
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_n_s_utf8); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 1411, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "pywrapfst.pyx":1549
+  /* "pywrapfst.pyx":1586
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 1549, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__3);
-  __Pyx_GIVEREF(__pyx_tuple__3);
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 1586, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
 
-  /* "pywrapfst.pyx":1571
+  /* "pywrapfst.pyx":1608
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 1571, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__4);
-  __Pyx_GIVEREF(__pyx_tuple__4);
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 1608, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "pywrapfst.pyx":1593
+  /* "pywrapfst.pyx":1630
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 1593, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__5);
-  __Pyx_GIVEREF(__pyx_tuple__5);
+  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1630, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
 
-  /* "pywrapfst.pyx":1734
+  /* "pywrapfst.pyx":1794
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  * 
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  */
-  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 1734, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__6);
-  __Pyx_GIVEREF(__pyx_tuple__6);
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 1794, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__10);
+  __Pyx_GIVEREF(__pyx_tuple__10);
 
-  /* "pywrapfst.pyx":1738
+  /* "pywrapfst.pyx":1798
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  */
-  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 1738, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__7);
-  __Pyx_GIVEREF(__pyx_tuple__7);
+  __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 1798, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__11);
+  __Pyx_GIVEREF(__pyx_tuple__11);
 
-  /* "pywrapfst.pyx":1740
+  /* "pywrapfst.pyx":1800
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_weight_t); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 1740, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__8);
-  __Pyx_GIVEREF(__pyx_tuple__8);
+  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_weight_t); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 1800, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__12);
+  __Pyx_GIVEREF(__pyx_tuple__12);
 
-  /* "pywrapfst.pyx":1905
+  /* "pywrapfst.pyx":1965
  *     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_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1905, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__9);
-  __Pyx_GIVEREF(__pyx_tuple__9);
+  __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 1965, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__13);
+  __Pyx_GIVEREF(__pyx_tuple__13);
 
-  /* "pywrapfst.pyx":1935
+  /* "pywrapfst.pyx":1995
  *     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_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 1935, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__10);
-  __Pyx_GIVEREF(__pyx_tuple__10);
+  __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 1995, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__14);
+  __Pyx_GIVEREF(__pyx_tuple__14);
 
-  /* "pywrapfst.pyx":2190
+  /* "pywrapfst.pyx":2264
  *         _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_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_No_relabeling_pairs_specified); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 2190, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__19);
-  __Pyx_GIVEREF(__pyx_tuple__19);
+  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_No_relabeling_pairs_specified); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 2264, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__23);
+  __Pyx_GIVEREF(__pyx_tuple__23);
 
-  /* "pywrapfst.pyx":2229
+  /* "pywrapfst.pyx":2303
  *                             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_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_No_new_SymbolTables_specified); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 2229, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__20);
-  __Pyx_GIVEREF(__pyx_tuple__20);
+  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_No_new_SymbolTables_specified); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(0, 2303, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__24);
+  __Pyx_GIVEREF(__pyx_tuple__24);
 
-  /* "pywrapfst.pyx":2297
+  /* "pywrapfst.pyx":2371
  *   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_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 2297, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__21);
-  __Pyx_GIVEREF(__pyx_tuple__21);
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 2371, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
 
-  /* "pywrapfst.pyx":2420
+  /* "pywrapfst.pyx":2494
  *   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_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 2420, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
+  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 2494, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__30);
+  __Pyx_GIVEREF(__pyx_tuple__30);
 
-  /* "pywrapfst.pyx":2424
+  /* "pywrapfst.pyx":2498
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_weight); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 2424, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__27);
-  __Pyx_GIVEREF(__pyx_tuple__27);
+  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_weight); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 2498, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__31);
+  __Pyx_GIVEREF(__pyx_tuple__31);
 
-  /* "pywrapfst.pyx":2469
+  /* "pywrapfst.pyx":2595
  *   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_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 2469, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
+  __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(0, 2595, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__32);
+  __Pyx_GIVEREF(__pyx_tuple__32);
 
-  /* "pywrapfst.pyx":2547
+  /* "pywrapfst.pyx":2621
  *     # 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_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_Cannot_topsort_cyclic_FST); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 2547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__29);
-  __Pyx_GIVEREF(__pyx_tuple__29);
+  __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_Cannot_topsort_cyclic_FST); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 2621, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__33);
+  __Pyx_GIVEREF(__pyx_tuple__33);
 
-  /* "pywrapfst.pyx":2616
+  /* "pywrapfst.pyx":2690
  * cdef _Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _Fst ofst = _Fst.__new__(_Fst)
  *   ofst._fst.reset(<FstClass_ptr> tfst)
  */
-  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 2616, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__30);
-  __Pyx_GIVEREF(__pyx_tuple__30);
+  __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 2690, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__34);
+  __Pyx_GIVEREF(__pyx_tuple__34);
 
-  /* "pywrapfst.pyx":2624
+  /* "pywrapfst.pyx":2698
  * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True):
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
  *   ofst._fst.reset(<MutableFstClass_ptr> tfst)
  */
-  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 2624, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__31);
-  __Pyx_GIVEREF(__pyx_tuple__31);
+  __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_s_Operation_failed); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(0, 2698, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__35);
+  __Pyx_GIVEREF(__pyx_tuple__35);
 
-  /* "pywrapfst.pyx":2882
+  /* "pywrapfst.pyx":2979
  *   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_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(0, 2882, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__32);
-  __Pyx_GIVEREF(__pyx_tuple__32);
+  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 2979, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__36);
+  __Pyx_GIVEREF(__pyx_tuple__36);
 
-  /* "pywrapfst.pyx":3020
+  /* "pywrapfst.pyx":3091
  *   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_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 3020, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__33);
-  __Pyx_GIVEREF(__pyx_tuple__33);
+  __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_s_State_index_out_of_range); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 3091, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__37);
+  __Pyx_GIVEREF(__pyx_tuple__37);
 
-  /* "pywrapfst.pyx":3566
+  /* "pywrapfst.pyx":3587
  *                                     addr(error))
  *   if error:
  *     raise FstOpError("Equivalence test encountered error")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-  __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_s_Equivalence_test_encountered_err); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(0, 3566, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__42);
-  __Pyx_GIVEREF(__pyx_tuple__42);
+  __pyx_tuple__46 = PyTuple_Pack(1, __pyx_kp_s_Equivalence_test_encountered_err); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(0, 3587, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__46);
+  __Pyx_GIVEREF(__pyx_tuple__46);
 
-  /* "pywrapfst.pyx":3762
+  /* "pywrapfst.pyx":3783
  *                                         addr(error))
  *   if error:
  *     raise FstOpError("Random equivalence test encountered error")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-  __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_Random_equivalence_test_encounte); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(0, 3762, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__49);
-  __Pyx_GIVEREF(__pyx_tuple__49);
+  __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_Random_equivalence_test_encounte); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(0, 3783, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__53);
+  __Pyx_GIVEREF(__pyx_tuple__53);
 
-  /* "pywrapfst.pyx":4212
+  /* "pywrapfst.pyx":4233
  *     self._sstrm.reset(new stringstream())
  *     if tfst == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
  *     return _init_XFst(tfst)
  * 
  */
-  __pyx_tuple__61 = PyTuple_Pack(1, __pyx_kp_s_Compilation_failed); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(0, 4212, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__61);
-  __Pyx_GIVEREF(__pyx_tuple__61);
+  __pyx_tuple__65 = PyTuple_Pack(1, __pyx_kp_s_Compilation_failed); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 4233, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__65);
+  __Pyx_GIVEREF(__pyx_tuple__65);
 
-  /* "pywrapfst.pyx":4497
+  /* "pywrapfst.pyx":4499
  *     # 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_tuple__62 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_arc_type); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 4497, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__62);
-  __Pyx_GIVEREF(__pyx_tuple__62);
+  __pyx_tuple__66 = PyTuple_Pack(1, __pyx_kp_s_Incompatible_or_invalid_arc_type); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 4499, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__66);
+  __Pyx_GIVEREF(__pyx_tuple__66);
 
-  /* "pywrapfst.pyx":4500
+  /* "pywrapfst.pyx":4502
  *     # 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_tuple__63 = PyTuple_Pack(1, __pyx_kp_s_Key_out_of_order); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 4500, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__63);
-  __Pyx_GIVEREF(__pyx_tuple__63);
+  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_kp_s_Key_out_of_order); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 4502, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__67);
+  __Pyx_GIVEREF(__pyx_tuple__67);
 
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":455
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_tuple__64 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__64);
-  __Pyx_GIVEREF(__pyx_tuple__64);
-  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_plus, 450, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 450, __pyx_L1_error)
+  __pyx_tuple__68 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__68);
+  __Pyx_GIVEREF(__pyx_tuple__68);
+  __pyx_codeobj__69 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__68, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_plus, 455, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__69)) __PYX_ERR(0, 455, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":487
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_tuple__66 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__66);
-  __Pyx_GIVEREF(__pyx_tuple__66);
-  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_times, 482, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 482, __pyx_L1_error)
+  __pyx_tuple__70 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 487, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__70);
+  __Pyx_GIVEREF(__pyx_tuple__70);
+  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_times, 487, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) __PYX_ERR(0, 487, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":519
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_tuple__68 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__68);
-  __Pyx_GIVEREF(__pyx_tuple__68);
-  __pyx_codeobj__69 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__68, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_divide, 514, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__69)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __pyx_tuple__72 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 519, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__72);
+  __Pyx_GIVEREF(__pyx_tuple__72);
+  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_divide, 519, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 519, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":552
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
- *   times(lhs, rhs)
+ *   power(lhs, rhs)
  */
-  __pyx_tuple__70 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__70);
-  __Pyx_GIVEREF(__pyx_tuple__70);
-  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_power, 547, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) __PYX_ERR(0, 547, __pyx_L1_error)
+  __pyx_tuple__74 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 552, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__74);
+  __Pyx_GIVEREF(__pyx_tuple__74);
+  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_power, 552, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 552, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2688
+  /* "pywrapfst.pyx":2764
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_tuple__72 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2688, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__72);
-  __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_new, 2688, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2688, __pyx_L1_error)
-  __pyx_tuple__74 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2688, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__74);
-  __Pyx_GIVEREF(__pyx_tuple__74);
+  __pyx_tuple__76 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 2764, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__76);
+  __Pyx_GIVEREF(__pyx_tuple__76);
+  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_new, 2764, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 2764, __pyx_L1_error)
+  __pyx_tuple__78 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__78)) __PYX_ERR(0, 2764, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__78);
+  __Pyx_GIVEREF(__pyx_tuple__78);
 
-  /* "pywrapfst.pyx":2692
+  /* "pywrapfst.pyx":2768
  * 
  *    @staticmethod
  *    def read(filename, fst_type=None):             # <<<<<<<<<<<<<<
  *      """
  *      read(filename, fst_type=None)
  */
-  __pyx_tuple__75 = PyTuple_Pack(2, __pyx_n_s_filename, __pyx_n_s_fst_type); if (unlikely(!__pyx_tuple__75)) __PYX_ERR(0, 2692, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__75);
-  __Pyx_GIVEREF(__pyx_tuple__75);
-  __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_read, 2692, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) __PYX_ERR(0, 2692, __pyx_L1_error)
-  __pyx_tuple__77 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__77)) __PYX_ERR(0, 2692, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__77);
-  __Pyx_GIVEREF(__pyx_tuple__77);
+  __pyx_tuple__79 = PyTuple_Pack(2, __pyx_n_s_filename, __pyx_n_s_fst_type); if (unlikely(!__pyx_tuple__79)) __PYX_ERR(0, 2768, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__79);
+  __Pyx_GIVEREF(__pyx_tuple__79);
+  __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_read, 2768, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) __PYX_ERR(0, 2768, __pyx_L1_error)
+  __pyx_tuple__81 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__81)) __PYX_ERR(0, 2768, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__81);
+  __Pyx_GIVEREF(__pyx_tuple__81);
 
-  /* "pywrapfst.pyx":2713
+  /* "pywrapfst.pyx":2789
  * 
  *    @staticmethod
  *    def read_from_string(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
  *      """
  *      read_from_string(fst_string, fst_type=None)
  */
-  __pyx_tuple__78 = PyTuple_Pack(2, __pyx_n_s_fst_string, __pyx_n_s_fst_type); if (unlikely(!__pyx_tuple__78)) __PYX_ERR(0, 2713, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__78);
-  __Pyx_GIVEREF(__pyx_tuple__78);
-  __pyx_codeobj__79 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__78, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_read_from_string, 2713, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__79)) __PYX_ERR(0, 2713, __pyx_L1_error)
-  __pyx_tuple__80 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__80)) __PYX_ERR(0, 2713, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__80);
-  __Pyx_GIVEREF(__pyx_tuple__80);
+  __pyx_tuple__82 = PyTuple_Pack(2, __pyx_n_s_fst_string, __pyx_n_s_fst_type); if (unlikely(!__pyx_tuple__82)) __PYX_ERR(0, 2789, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__82);
+  __Pyx_GIVEREF(__pyx_tuple__82);
+  __pyx_codeobj__83 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__82, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_read_from_string, 2789, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__83)) __PYX_ERR(0, 2789, __pyx_L1_error)
+  __pyx_tuple__84 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__84)) __PYX_ERR(0, 2789, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__84);
+  __Pyx_GIVEREF(__pyx_tuple__84);
 
-  /* "pywrapfst.pyx":3963
+  /* "pywrapfst.pyx":3984
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__81 = PyTuple_Pack(9, __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_result, __pyx_n_s_it); if (unlikely(!__pyx_tuple__81)) __PYX_ERR(0, 3963, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__81);
-  __Pyx_GIVEREF(__pyx_tuple__81);
-  __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(5, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_shortestdistance, 3963, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) __PYX_ERR(0, 3963, __pyx_L1_error)
+  __pyx_tuple__85 = PyTuple_Pack(9, __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_result, __pyx_n_s_it); if (unlikely(!__pyx_tuple__85)) __PYX_ERR(0, 3984, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__85);
+  __Pyx_GIVEREF(__pyx_tuple__85);
+  __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(5, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_shortestdistance, 3984, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) __PYX_ERR(0, 3984, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4536
+  /* "pywrapfst.pyx":4548
  * 
  * @atexit.register
  * def _reset_fst_error_fatal():             # <<<<<<<<<<<<<<
  *   fst.FLAGS_fst_error_fatal = _fst_error_fatal_old
  * 
  */
-  __pyx_codeobj__83 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_reset_fst_error_fatal, 4536, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__83)) __PYX_ERR(0, 4536, __pyx_L1_error)
+  __pyx_codeobj__87 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_usr_local_google_home_kbg_scrat, __pyx_n_s_reset_fst_error_fatal, 4548, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__87)) __PYX_ERR(0, 4548, __pyx_L1_error)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -49501,10 +49203,10 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst_Weight.copy = (struct __pyx_obj_9pywrapfst_Weight *(*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_copy;
   __pyx_vtable_9pywrapfst_Weight.to_string = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_to_string;
   __pyx_vtable_9pywrapfst_Weight.type = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_type;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 348, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 343, __pyx_L1_error)
   __pyx_type_9pywrapfst_Weight.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 348, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "Weight", (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 348, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 343, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "Weight", (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 343, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Weight = &__pyx_type_9pywrapfst_Weight;
   __pyx_vtabptr_9pywrapfst__SymbolTable = &__pyx_vtable_9pywrapfst__SymbolTable;
   __pyx_vtable_9pywrapfst__SymbolTable.available_key = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_available_key;
@@ -49517,26 +49219,26 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst__SymbolTable.num_symbols = (size_t (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_num_symbols;
   __pyx_vtable_9pywrapfst__SymbolTable.write = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write;
   __pyx_vtable_9pywrapfst__SymbolTable.write_text = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write_text;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 674, __pyx_L1_error)
   __pyx_type_9pywrapfst__SymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_SymbolTable", (PyObject *)&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 674, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_SymbolTable", (PyObject *)&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 674, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__SymbolTable = &__pyx_type_9pywrapfst__SymbolTable;
   __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable = &__pyx_vtable_9pywrapfst__EncodeMapperSymbolTable;
   __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, 821, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 851, __pyx_L1_error)
   __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 821, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_EncodeMapperSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 821, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 851, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_EncodeMapperSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 851, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable = &__pyx_type_9pywrapfst__EncodeMapperSymbolTable;
   __pyx_vtabptr_9pywrapfst__FstSymbolTable = &__pyx_vtable_9pywrapfst__FstSymbolTable;
   __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, 841, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 871, __pyx_L1_error)
   __pyx_type_9pywrapfst__FstSymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 841, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_FstSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 841, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 871, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_FstSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 871, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__FstSymbolTable = &__pyx_type_9pywrapfst__FstSymbolTable;
   __pyx_vtabptr_9pywrapfst__MutableSymbolTable = &__pyx_vtable_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
@@ -49544,26 +49246,26 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst__MutableSymbolTable.add_table = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.set_name = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_set_name;
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 860, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 890, __pyx_L1_error)
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 860, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_MutableSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 860, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 890, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_MutableSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 890, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableSymbolTable = &__pyx_type_9pywrapfst__MutableSymbolTable;
   __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable = &__pyx_vtable_9pywrapfst__MutableFstSymbolTable;
   __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, 911, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
   __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 911, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_MutableFstSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 911, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_MutableFstSymbolTable", (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableFstSymbolTable = &__pyx_type_9pywrapfst__MutableFstSymbolTable;
   __pyx_vtabptr_9pywrapfst_SymbolTable = &__pyx_vtable_9pywrapfst_SymbolTable;
   __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, 931, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 952, __pyx_L1_error)
   __pyx_type_9pywrapfst_SymbolTable.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 931, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "SymbolTable", (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 931, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 952, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "SymbolTable", (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 952, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_SymbolTable = &__pyx_type_9pywrapfst_SymbolTable;
   __pyx_vtabptr_9pywrapfst_SymbolTableIterator = &__pyx_vtable_9pywrapfst_SymbolTableIterator;
   __pyx_vtable_9pywrapfst_SymbolTableIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_done;
@@ -49571,10 +49273,10 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst_SymbolTableIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_reset;
   __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, 1121, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1135, __pyx_L1_error)
   __pyx_type_9pywrapfst_SymbolTableIterator.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableIterator.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1121, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "SymbolTableIterator", (PyObject *)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1121, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableIterator.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1135, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "SymbolTableIterator", (PyObject *)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1135, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_SymbolTableIterator = &__pyx_type_9pywrapfst_SymbolTableIterator;
   __pyx_vtabptr_9pywrapfst_EncodeMapper = &__pyx_vtable_9pywrapfst_EncodeMapper;
   __pyx_vtable_9pywrapfst_EncodeMapper.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_arc_type;
@@ -49585,11 +49287,11 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst_EncodeMapper.set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols;
   __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, 1221, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1217, __pyx_L1_error)
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
   #if CYTHON_COMPILING_IN_CPYTHON
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1221, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1217, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_6__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_6__call__.doc = __pyx_doc_9pywrapfst_12EncodeMapper_6__call__;
@@ -49597,8 +49299,8 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "EncodeMapper", (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1217, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "EncodeMapper", (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1217, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_EncodeMapper = &__pyx_type_9pywrapfst_EncodeMapper;
   __pyx_vtabptr_9pywrapfst__Fst = &__pyx_vtable_9pywrapfst__Fst;
   __pyx_vtable_9pywrapfst__Fst.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_arc_type;
@@ -49619,11 +49321,11 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst__Fst.verify = (bool (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_verify;
   __pyx_vtable_9pywrapfst__Fst.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_weight_type;
   __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.WriteToString = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_WriteToString;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1352, __pyx_L1_error)
+  __pyx_vtable_9pywrapfst__Fst.write_to_string = (std::string (*)(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, 1373, __pyx_L1_error)
   __pyx_type_9pywrapfst__Fst.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__Fst.tp_dict, __pyx_vtabptr_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1352, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_Fst", (PyObject *)&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1352, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__Fst.tp_dict, __pyx_vtabptr_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1373, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_Fst", (PyObject *)&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1373, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__Fst = &__pyx_type_9pywrapfst__Fst;
   __pyx_vtabptr_9pywrapfst__MutableFst = &__pyx_vtable_9pywrapfst__MutableFst;
   __pyx_vtable_9pywrapfst__MutableFst.__pyx_base = *__pyx_vtabptr_9pywrapfst__Fst;
@@ -49659,17 +49361,17 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __pyx_vtable_9pywrapfst__MutableFst._topsort = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__topsort;
   __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, 1718, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1778, __pyx_L1_error)
   __pyx_type_9pywrapfst__MutableFst.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1718, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "_MutableFst", (PyObject *)&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1718, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1778, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "_MutableFst", (PyObject *)&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1778, __pyx_L1_error)
   __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, 2799, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2898, __pyx_L1_error)
   __pyx_type_9pywrapfst_Arc.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2799, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "Arc", (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2799, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2898, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "Arc", (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2898, __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;
@@ -49680,10 +49382,10 @@ PyMODINIT_FUNC PyInit_pywrapfst(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, 2867, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2966, __pyx_L1_error)
   __pyx_type_9pywrapfst_ArcIterator.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2867, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "ArcIterator", (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2867, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2966, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "ArcIterator", (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 2966, __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;
@@ -49695,28 +49397,28 @@ PyMODINIT_FUNC PyInit_pywrapfst(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, 3004, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3077, __pyx_L1_error)
   __pyx_type_9pywrapfst_MutableArcIterator.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "MutableArcIterator", (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3077, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "MutableArcIterator", (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3077, __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, 3156, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3191, __pyx_L1_error)
   __pyx_type_9pywrapfst_StateIterator.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3156, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "StateIterator", (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3156, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3191, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "StateIterator", (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3191, __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, 4111, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4132, __pyx_L1_error)
   __pyx_type_9pywrapfst_Compiler.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4111, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "Compiler", (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4111, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4132, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "Compiler", (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4132, __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;
@@ -49728,10 +49430,10 @@ PyMODINIT_FUNC PyInit_pywrapfst(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, 4237, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4258, __pyx_L1_error)
   __pyx_type_9pywrapfst_FarReader.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4237, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "FarReader", (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4237, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4258, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "FarReader", (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4258, __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;
@@ -49739,10 +49441,10 @@ PyMODINIT_FUNC PyInit_pywrapfst(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, 4411, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4416, __pyx_L1_error)
   __pyx_type_9pywrapfst_FarWriter.tp_print = 0;
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4411, __pyx_L1_error)
-  if (PyObject_SetAttrString(__pyx_m, "FarWriter", (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4411, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4416, __pyx_L1_error)
+  if (PyObject_SetAttrString(__pyx_m, "FarWriter", (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4416, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarWriter = &__pyx_type_9pywrapfst_FarWriter;
   /*--- Type import code ---*/
   /*--- Variable import code ---*/
@@ -49998,1556 +49700,1647 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":151
- * 
- * 
- * class FstUnknownWeightTypeError(FstError, ValueError):             # <<<<<<<<<<<<<<
- * 
- *   pass
- */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
-  __Pyx_INCREF(__pyx_builtin_ValueError);
-  __Pyx_GIVEREF(__pyx_builtin_ValueError);
-  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_ValueError);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstUnknownWeightTypeError, __pyx_n_s_FstUnknownWeightTypeError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstUnknownWeightTypeError, __pyx_t_2, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstUnknownWeightTypeError, __pyx_t_4) < 0) __PYX_ERR(0, 151, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "pywrapfst.pyx":407
+  /* "pywrapfst.pyx":402
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.Zero(weight_type)
  */
-  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_Zero); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 407, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_Zero); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 402, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":406
+  /* "pywrapfst.pyx":401
  *   # the C part out-of-class and then call it from within.
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def Zero(cls, weight_type):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 406, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_Zero, __pyx_t_1) < 0) __PYX_ERR(0, 407, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 401, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_Zero, __pyx_t_2) < 0) __PYX_ERR(0, 402, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":414
+  /* "pywrapfst.pyx":411
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.One(weight_type)
  */
-  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_One); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 414, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_One); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 411, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":413
+  /* "pywrapfst.pyx":410
  *     return _Weight_Zero(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def One(cls, weight_type):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 413, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_One, __pyx_t_2) < 0) __PYX_ERR(0, 414, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 410, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_One, __pyx_t_1) < 0) __PYX_ERR(0, 411, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":421
+  /* "pywrapfst.pyx":420
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.NoWeight(weight_type)
  */
-  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_NoWeight); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 421, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_NoWeight); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 420, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":420
+  /* "pywrapfst.pyx":419
  *     return _Weight_One(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def NoWeight(cls, weight_type):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 420, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_NoWeight, __pyx_t_1) < 0) __PYX_ERR(0, 421, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 419, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_NoWeight, __pyx_t_2) < 0) __PYX_ERR(0, 420, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":455
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_1) < 0) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_2) < 0) __PYX_ERR(0, 455, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":487
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_1) < 0) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 487, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_2) < 0) __PYX_ERR(0, 487, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":519
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_1) < 0) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 519, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_2) < 0) __PYX_ERR(0, 519, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":552
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
- *   times(lhs, rhs)
+ *   power(lhs, rhs)
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_1) < 0) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 552, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_2) < 0) __PYX_ERR(0, 552, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":964
+  /* "pywrapfst.pyx":977
  * 
  *   @classmethod
  *   def read(cls, filename):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read(filename)
  */
-  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 964, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 977, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":963
+  /* "pywrapfst.pyx":976
  *     self._smart_table.reset(self._table)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, filename):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 963, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 964, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 976, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 977, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":986
+  /* "pywrapfst.pyx":999
  * 
  *   @classmethod
  *   def read_text(cls, filename, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_text(filename)
  */
-  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 986, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 999, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":985
+  /* "pywrapfst.pyx":998
  *     return _init_SymbolTable(tsyms)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_text(cls, filename, bool allow_negative_labels=False):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 985, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_1) < 0) __PYX_ERR(0, 986, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 998, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_2) < 0) __PYX_ERR(0, 999, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1013
+  /* "pywrapfst.pyx":1026
  * 
  *   @classmethod
  *   def read_fst(cls, filename, bool input_table):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_fst(filename, input_table)
  */
-  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1013, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1026, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1012
+  /* "pywrapfst.pyx":1025
  *     return _init_SymbolTable(tsyms)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_fst(cls, filename, bool input_table):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1012, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_2) < 0) __PYX_ERR(0, 1013, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1025, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_1) < 0) __PYX_ERR(0, 1026, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":2008
+  /* "pywrapfst.pyx":2068
  *     return self
  * 
  *   cdef void _minimize(self, float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  */
-  __pyx_k__11 = fst::kDelta;
+  __pyx_k__15 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2014
+  /* "pywrapfst.pyx":2074
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
  *     """
  *     minimize(self, delta=0.0009765625, allow_nondet=False)
  */
-  __pyx_k__12 = fst::kDelta;
+  __pyx_k__16 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2100
+  /* "pywrapfst.pyx":2174
  *     return self
  * 
  *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                    weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  */
-  __pyx_k__13 = fst::kDelta;
-  __pyx_k__14 = fst::kNoStateId;
+  __pyx_k__17 = fst::kDelta;
+  __pyx_k__18 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2109
+  /* "pywrapfst.pyx":2183
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):
  */
-  __pyx_k__15 = fst::kDelta;
+  __pyx_k__19 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2110
+  /* "pywrapfst.pyx":2184
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *             weight=None):
  *     """
  */
-  __pyx_k__16 = fst::kNoStateId;
+  __pyx_k__20 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2137
+  /* "pywrapfst.pyx":2211
  * 
  *   cdef void _push(self,
  *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                   bool remove_total_weight=False,
  *                   bool to_final=False) except *:
  */
-  __pyx_k__17 = fst::kDelta;
+  __pyx_k__21 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2145
+  /* "pywrapfst.pyx":2219
  * 
  *   def push(self,
  *            float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *            bool remove_total_weight=False,
  *            bool to_final=False):
  */
-  __pyx_k__18 = fst::kDelta;
+  __pyx_k__22 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2380
+  /* "pywrapfst.pyx":2454
  *   cdef void _rmepsilon(self,
  *                        bool connect=True,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None) except *:
  */
-  __pyx_k__22 = fst::kDelta;
+  __pyx_k__26 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2381
+  /* "pywrapfst.pyx":2455
  *                        bool connect=True,
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                        weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if weight unspecified.
  */
-  __pyx_k__23 = fst::kNoStateId;
+  __pyx_k__27 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2391
+  /* "pywrapfst.pyx":2465
  *   def rmepsilon(self,
  *                 bool connect=True,
  *                 float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                 int64 nstate=fst.kNoStateId,
  *                 weight=None):
  */
-  __pyx_k__24 = fst::kDelta;
+  __pyx_k__28 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2392
+  /* "pywrapfst.pyx":2466
  *                 bool connect=True,
  *                 float delta=fst.kDelta,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                 weight=None):
  *     """
  */
-  __pyx_k__25 = fst::kNoStateId;
+  __pyx_k__29 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2671
- *   return _init_XFst(ofst)
+  /* "pywrapfst.pyx":2747
+ * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2671, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2747, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_builtin_object);
   __Pyx_GIVEREF(__pyx_builtin_object);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_builtin_object);
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2671, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_Fst, __pyx_n_s_Fst, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2671, __pyx_L1_error)
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2747, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_Fst, __pyx_n_s_Fst, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2747, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2688
+  /* "pywrapfst.pyx":2764
  *    """
  * 
  *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
  *     return _create_Fst(arc_type)
  * 
  */
-  __pyx_t_4 = __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__73)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2688, __pyx_L1_error)
+  __pyx_t_4 = __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__77)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2764, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__74);
-  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_new, __pyx_t_4) < 0) __PYX_ERR(0, 2688, __pyx_L1_error)
+  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__78);
+  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_new, __pyx_t_4) < 0) __PYX_ERR(0, 2764, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2692
+  /* "pywrapfst.pyx":2768
  * 
  *    @staticmethod
  *    def read(filename, fst_type=None):             # <<<<<<<<<<<<<<
  *      """
  *      read(filename, fst_type=None)
  */
-  __pyx_t_4 = __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__76)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2692, __pyx_L1_error)
+  __pyx_t_4 = __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__80)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2768, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__77);
+  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__81);
 
-  /* "pywrapfst.pyx":2691
+  /* "pywrapfst.pyx":2767
  *     return _create_Fst(arc_type)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
  *    def read(filename, fst_type=None):
  *      """
  */
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2691, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2767, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_staticmethod, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2691, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_staticmethod, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2767, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2692, __pyx_L1_error)
+  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2768, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2713
+  /* "pywrapfst.pyx":2789
  * 
  *    @staticmethod
  *    def read_from_string(fst_string, fst_type=None):             # <<<<<<<<<<<<<<
  *      """
  *      read_from_string(fst_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__79)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2713, __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__83)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2789, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__80);
+  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__84);
 
-  /* "pywrapfst.pyx":2712
+  /* "pywrapfst.pyx":2788
  *      return _read_Fst(filename, fst_type)
  * 
  *    @staticmethod             # <<<<<<<<<<<<<<
  *    def read_from_string(fst_string, fst_type=None):
  *      """
  */
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2712, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2788, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
   __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_staticmethod, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2712, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_staticmethod, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2788, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_read_from_string, __pyx_t_4) < 0) __PYX_ERR(0, 2713, __pyx_L1_error)
+  if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_read_from_string, __pyx_t_4) < 0) __PYX_ERR(0, 2789, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":2671
- *   return _init_XFst(ofst)
+  /* "pywrapfst.pyx":2747
+ * 
  * 
  * class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *    """
  */
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst, __pyx_t_2, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2671, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_Fst, __pyx_t_1, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2747, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst, __pyx_t_4) < 0) __PYX_ERR(0, 2671, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst, __pyx_t_4) < 0) __PYX_ERR(0, 2747, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2736
+  /* "pywrapfst.pyx":2815
  * 
  * 
  * EXPANDED = fst.kExpanded             # <<<<<<<<<<<<<<
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2736, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_2) < 0) __PYX_ERR(0, 2736, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2815, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2815, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2737
+  /* "pywrapfst.pyx":2816
  * 
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable             # <<<<<<<<<<<<<<
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2737, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_2) < 0) __PYX_ERR(0, 2737, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2816, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2738
+  /* "pywrapfst.pyx":2817
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError             # <<<<<<<<<<<<<<
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2738, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_2) < 0) __PYX_ERR(0, 2738, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2817, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2817, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2739
+  /* "pywrapfst.pyx":2818
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor             # <<<<<<<<<<<<<<
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2739, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_2) < 0) __PYX_ERR(0, 2739, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2818, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2818, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2740
+  /* "pywrapfst.pyx":2819
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor             # <<<<<<<<<<<<<<
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2740, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_2) < 0) __PYX_ERR(0, 2740, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2819, __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, 2819, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2741
+  /* "pywrapfst.pyx":2820
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic             # <<<<<<<<<<<<<<
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2741, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2741, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2820, __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, 2820, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2742
+  /* "pywrapfst.pyx":2821
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic             # <<<<<<<<<<<<<<
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2742, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2742, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2821, __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, 2821, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2743
+  /* "pywrapfst.pyx":2822
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic             # <<<<<<<<<<<<<<
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2743, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2743, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2822, __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, 2822, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2744
+  /* "pywrapfst.pyx":2823
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic             # <<<<<<<<<<<<<<
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2744, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2744, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2823, __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, 2823, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2745
+  /* "pywrapfst.pyx":2824
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons             # <<<<<<<<<<<<<<
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2745, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2745, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2824, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2824, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2746
+  /* "pywrapfst.pyx":2825
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons             # <<<<<<<<<<<<<<
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2746, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2746, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2825, __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, 2825, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2747
+  /* "pywrapfst.pyx":2826
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons             # <<<<<<<<<<<<<<
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2747, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2747, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2826, __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, 2826, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2748
+  /* "pywrapfst.pyx":2827
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons             # <<<<<<<<<<<<<<
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2748, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2748, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2827, __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, 2827, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2749
+  /* "pywrapfst.pyx":2828
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2749, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2749, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2828, __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, 2828, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2750
+  /* "pywrapfst.pyx":2829
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2750, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2750, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2829, __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, 2829, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2751
+  /* "pywrapfst.pyx":2830
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2751, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2751, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2830, __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, 2830, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2752
+  /* "pywrapfst.pyx":2831
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2752, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2752, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2831, __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, 2831, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2753
+  /* "pywrapfst.pyx":2832
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2753, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2753, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2832, __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, 2832, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2754
+  /* "pywrapfst.pyx":2833
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2754, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2754, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2833, __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, 2833, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2755
+  /* "pywrapfst.pyx":2834
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted             # <<<<<<<<<<<<<<
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2755, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_2) < 0) __PYX_ERR(0, 2755, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2834, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2834, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2756
+  /* "pywrapfst.pyx":2835
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted             # <<<<<<<<<<<<<<
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2756, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_2) < 0) __PYX_ERR(0, 2756, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2835, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2835, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2757
+  /* "pywrapfst.pyx":2836
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic             # <<<<<<<<<<<<<<
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2757, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 2757, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2836, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2836, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2758
+  /* "pywrapfst.pyx":2837
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic             # <<<<<<<<<<<<<<
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2758, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 2758, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2837, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2837, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2759
+  /* "pywrapfst.pyx":2838
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic             # <<<<<<<<<<<<<<
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2759, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 2759, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2838, __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, 2838, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2760
+  /* "pywrapfst.pyx":2839
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic             # <<<<<<<<<<<<<<
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2760, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 2760, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2839, __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, 2839, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2761
+  /* "pywrapfst.pyx":2840
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted             # <<<<<<<<<<<<<<
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2761, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2761, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2840, __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, 2840, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2762
+  /* "pywrapfst.pyx":2841
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted             # <<<<<<<<<<<<<<
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2762, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 2762, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); 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_NOT_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2841, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2763
+  /* "pywrapfst.pyx":2842
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible             # <<<<<<<<<<<<<<
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2763, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 2763, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); 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_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2842, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2764
+  /* "pywrapfst.pyx":2843
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible             # <<<<<<<<<<<<<<
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2764, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 2764, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); 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_NOT_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2843, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2765
+  /* "pywrapfst.pyx":2844
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible             # <<<<<<<<<<<<<<
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2765, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 2765, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2844, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2844, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2766
+  /* "pywrapfst.pyx":2845
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible             # <<<<<<<<<<<<<<
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2766, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 2766, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2845, __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, 2845, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2767
+  /* "pywrapfst.pyx":2846
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString             # <<<<<<<<<<<<<<
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2767, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_2) < 0) __PYX_ERR(0, 2767, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2846, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2846, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2768
+  /* "pywrapfst.pyx":2847
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString             # <<<<<<<<<<<<<<
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2768, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_2) < 0) __PYX_ERR(0, 2768, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2847, __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, 2847, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2769
+  /* "pywrapfst.pyx":2848
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles             # <<<<<<<<<<<<<<
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2769, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_2) < 0) __PYX_ERR(0, 2769, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2848, __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, 2848, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2770
+  /* "pywrapfst.pyx":2849
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles             # <<<<<<<<<<<<<<
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2770, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_2) < 0) __PYX_ERR(0, 2770, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); 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_UNWEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2849, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2771
+  /* "pywrapfst.pyx":2850
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties             # <<<<<<<<<<<<<<
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2771, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2771, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); 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_NULL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2850, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2772
+  /* "pywrapfst.pyx":2851
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties             # <<<<<<<<<<<<<<
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2772, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2772, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); 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_COPY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2851, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2773
+  /* "pywrapfst.pyx":2852
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties             # <<<<<<<<<<<<<<
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2773, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2773, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); 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_INTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2852, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2774
+  /* "pywrapfst.pyx":2853
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties             # <<<<<<<<<<<<<<
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2774, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2774, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); 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_EXTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2853, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2775
+  /* "pywrapfst.pyx":2854
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2775, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2775, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); 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_SET_START_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2854, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2776
+  /* "pywrapfst.pyx":2855
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2776, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2776, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); 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_SET_FINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2855, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2777
+  /* "pywrapfst.pyx":2856
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2777, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2777, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); 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_ADD_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2856, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2778
+  /* "pywrapfst.pyx":2857
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2778, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2778, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); 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_ADD_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2857, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2779
+  /* "pywrapfst.pyx":2858
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2779, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2779, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); 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_SET_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2858, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2780
+  /* "pywrapfst.pyx":2859
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2780, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2780, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); 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_DELETE_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2859, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2781
+  /* "pywrapfst.pyx":2860
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2781, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2781, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); 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_DELETE_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2860, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2782
+  /* "pywrapfst.pyx":2861
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2782, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2782, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); 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_STATE_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2783
+  /* "pywrapfst.pyx":2862
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2783, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2783, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); 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_ARC_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2862, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2784
+  /* "pywrapfst.pyx":2863
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2784, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2784, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); 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_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2785
+  /* "pywrapfst.pyx":2864
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2785, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2785, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); 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_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2864, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2786
+  /* "pywrapfst.pyx":2865
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2786, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2786, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); 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_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2865, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2787
+  /* "pywrapfst.pyx":2866
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2787, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2787, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); 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_ADD_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2866, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2788
+  /* "pywrapfst.pyx":2867
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2788, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2788, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); 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_RM_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2867, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2789
+  /* "pywrapfst.pyx":2868
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2789, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2789, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); 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_BINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2868, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2790
+  /* "pywrapfst.pyx":2869
  * 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_2 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2790, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2790, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); 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_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2869, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2791
+  /* "pywrapfst.pyx":2870
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties             # <<<<<<<<<<<<<<
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2791, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2791, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); 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_POS_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2870, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2792
+  /* "pywrapfst.pyx":2871
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties             # <<<<<<<<<<<<<<
  * FST_PROPERTIES = fst.kFstProperties
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2792, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2792, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); 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_NEG_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2871, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2793
+  /* "pywrapfst.pyx":2872
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2793, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 2793, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); 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_FST_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2872, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3238
+  /* "pywrapfst.pyx":2878
+ * 
+ * 
+ * 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, 2878, __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, 2878, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2879
+ * 
+ * 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, 2879, __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, 2879, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2880
+ * 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, 2880, __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, 2880, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2881
+ * 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, 2881, __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, 2881, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2882
+ * 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, 2882, __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, 2882, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2883
+ * 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, 2883, __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, 2883, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2884
+ * 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, 2884, __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, 2884, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2890
+ * 
+ * 
+ * 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, 2890, __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, 2890, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2891
+ * 
+ * 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, 2891, __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, 2891, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":2892
+ * 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, 2892, __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, 2892, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":3259
  * 
  * cdef _Fst _map(_Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                map_type=b"identity",
  *                weight=None):
  */
-  __pyx_k__34 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3251
+  /* "pywrapfst.pyx":3272
  * 
  * cpdef _Fst arcmap(_Fst ifst,
  *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                   map_type=b"identity",
  *                   weight=None):
  */
-  __pyx_k__35 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3250
+  /* "pywrapfst.pyx":3271
  * 
  * 
  * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
  *                   float delta=fst.kDelta,
  *                   map_type=b"identity",
  */
-  __pyx_k__35 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3356
+  /* "pywrapfst.pyx":3377
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__36 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3358
+  /* "pywrapfst.pyx":3379
  *                               float delta=fst.kDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None,
  */
-  __pyx_k__37 = fst::kNoStateId;
+  __pyx_k__41 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3356
+  /* "pywrapfst.pyx":3377
  * 
  * cpdef _MutableFst determinize(_Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__36 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3358
+  /* "pywrapfst.pyx":3379
  *                               float delta=fst.kDelta,
  *                               det_type=b"functional",
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None,
  */
-  __pyx_k__37 = fst::kNoStateId;
+  __pyx_k__41 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3447
+  /* "pywrapfst.pyx":3468
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  */
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3448
+  /* "pywrapfst.pyx":3469
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                int64 subsequential_label=0,
  *                                weight=None):
  */
-  __pyx_k__39 = fst::kNoStateId;
+  __pyx_k__43 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3447
+  /* "pywrapfst.pyx":3468
  * 
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int64 nstate=fst.kNoStateId,
  *                                int64 subsequential_label=0,
  */
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3448
+  /* "pywrapfst.pyx":3469
  * cpdef _MutableFst disambiguate(_Fst ifst,
  *                                float delta=fst.kDelta,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                int64 subsequential_label=0,
  *                                weight=None):
  */
-  __pyx_k__39 = fst::kNoStateId;
+  __pyx_k__43 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3516
+  /* "pywrapfst.pyx":3537
  * 
  * 
  * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__40 = fst::kDelta;
-  __pyx_k__40 = fst::kDelta;
+  __pyx_k__44 = fst::kDelta;
+  __pyx_k__44 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3539
+  /* "pywrapfst.pyx":3560
  * 
  * 
  * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__41 = fst::kDelta;
-  __pyx_k__41 = fst::kDelta;
+  __pyx_k__45 = fst::kDelta;
+  __pyx_k__45 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3602
+  /* "pywrapfst.pyx":3623
  * 
  * 
  * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__43 = fst::kDelta;
-  __pyx_k__43 = fst::kDelta;
+  __pyx_k__47 = fst::kDelta;
+  __pyx_k__47 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3629
+  /* "pywrapfst.pyx":3650
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):
  */
-  __pyx_k__44 = fst::kDelta;
+  __pyx_k__48 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3630
+  /* "pywrapfst.pyx":3651
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                         weight=None):
  *   """
  */
-  __pyx_k__45 = fst::kNoStateId;
+  __pyx_k__49 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3629
+  /* "pywrapfst.pyx":3650
  * 
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                         int64 nstate=fst.kNoStateId,
  *                         weight=None):
  */
-  __pyx_k__44 = fst::kDelta;
+  __pyx_k__48 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3630
+  /* "pywrapfst.pyx":3651
  * cpdef _MutableFst prune(_Fst ifst,
  *                         float delta=fst.kDelta,
  *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                         weight=None):
  *   """
  */
-  __pyx_k__45 = fst::kNoStateId;
+  __pyx_k__49 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3661
+  /* "pywrapfst.pyx":3682
  * 
  * cpdef _MutableFst push(_Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                        bool push_weights=False,
  *                        bool push_labels=False,
  */
-  __pyx_k__46 = fst::kDelta;
+  __pyx_k__50 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3660
+  /* "pywrapfst.pyx":3681
  * 
  * 
  * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
  *                        float delta=fst.kDelta,
  *                        bool push_weights=False,
  */
-  __pyx_k__46 = fst::kDelta;
+  __pyx_k__50 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3715
+  /* "pywrapfst.pyx":3736
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__47 = fst::kDelta;
+  __pyx_k__51 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3718
+  /* "pywrapfst.pyx":3739
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
  *   """
  *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__48 = INT32_MAX;
+  __pyx_k__52 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3715
+  /* "pywrapfst.pyx":3736
  *                           _Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__47 = fst::kDelta;
+  __pyx_k__51 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3718
+  /* "pywrapfst.pyx":3739
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
  *   """
  *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__48 = INT32_MAX;
+  __pyx_k__52 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3770
+  /* "pywrapfst.pyx":3791
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
  *                           bool weighted=False,
  *                           bool remove_total_weight=False):
  */
-  __pyx_k__50 = INT32_MAX;
+  __pyx_k__54 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3766
+  /* "pywrapfst.pyx":3787
  * 
  * 
  * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
  *                           int32 npath=1,
  *                           time_t seed=0,
  */
-  __pyx_k__50 = INT32_MAX;
+  __pyx_k__54 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3903
+  /* "pywrapfst.pyx":3924
  * cpdef _MutableFst rmepsilon(_Fst ifst,
  *                             bool connect=True,
  *                             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                             int64 nstate=fst.kNoStateId,
  *                             queue_type=b"auto",
  */
-  __pyx_k__51 = fst::kDelta;
+  __pyx_k__55 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3904
+  /* "pywrapfst.pyx":3925
  *                             bool connect=True,
  *                             float delta=fst.kDelta,
  *                             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                             queue_type=b"auto",
  *                             bool reverse=False,
  */
-  __pyx_k__52 = fst::kNoStateId;
+  __pyx_k__56 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3903
+  /* "pywrapfst.pyx":3924
  * cpdef _MutableFst rmepsilon(_Fst ifst,
  *                             bool connect=True,
  *                             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                             int64 nstate=fst.kNoStateId,
  *                             queue_type=b"auto",
  */
-  __pyx_k__51 = fst::kDelta;
+  __pyx_k__55 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3904
+  /* "pywrapfst.pyx":3925
  *                             bool connect=True,
  *                             float delta=fst.kDelta,
  *                             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                             queue_type=b"auto",
  *                             bool reverse=False,
  */
-  __pyx_k__52 = fst::kNoStateId;
+  __pyx_k__56 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3944
+  /* "pywrapfst.pyx":3965
  * 
  * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
  *     float delta=fst.kDelta, int64 nstate=fst.kNoStateId, queue_type=b"auto",             # <<<<<<<<<<<<<<
  *     bool reverse=False) except *:
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  */
-  __pyx_k__53 = fst::kDelta;
-  __pyx_k__54 = fst::kNoStateId;
+  __pyx_k__57 = fst::kDelta;
+  __pyx_k__58 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3964
+  /* "pywrapfst.pyx":3985
  * 
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  */
-  __pyx_k__55 = fst::kDelta;
+  __pyx_k__59 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3965
+  /* "pywrapfst.pyx":3986
  * def shortestdistance(_Fst ifst,
  *                      float delta=fst.kDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                      queue_type=b"auto",
  *                      bool reverse=False):
  */
-  __pyx_k__56 = fst::kNoStateId;
+  __pyx_k__60 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3963
+  /* "pywrapfst.pyx":3984
  * 
  * 
  * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_49shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3963, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_2) < 0) __PYX_ERR(0, 3963, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_49shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3984, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 3984, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4009
+  /* "pywrapfst.pyx":4030
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__57 = fst::kDelta;
+  __pyx_k__61 = fst::kDelta;
 
-  /* "pywrapfst.pyx":4011
+  /* "pywrapfst.pyx":4032
  *                                float delta=fst.kDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                queue_type=b"auto",
  *                                bool unique=False,
  */
-  __pyx_k__58 = fst::kNoStateId;
+  __pyx_k__62 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4009
+  /* "pywrapfst.pyx":4030
  * 
  * cpdef _MutableFst shortestpath(_Fst ifst,
  *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__57 = fst::kDelta;
+  __pyx_k__61 = fst::kDelta;
 
-  /* "pywrapfst.pyx":4011
+  /* "pywrapfst.pyx":4032
  *                                float delta=fst.kDelta,
  *                                int32 nshortest=1,
  *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                                queue_type=b"auto",
  *                                bool unique=False,
  */
-  __pyx_k__58 = fst::kNoStateId;
+  __pyx_k__62 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4163
+  /* "pywrapfst.pyx":4184
  * 
  *   def __cinit__(self,
  *                 string fst_type=b"vector",             # <<<<<<<<<<<<<<
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  */
-  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4163, __pyx_L1_error)
-  __pyx_k__59 = __pyx_t_6;
+  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4184, __pyx_L1_error)
+  __pyx_k__63 = __pyx_t_6;
 
-  /* "pywrapfst.pyx":4164
+  /* "pywrapfst.pyx":4185
  *   def __cinit__(self,
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",             # <<<<<<<<<<<<<<
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  */
-  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4164, __pyx_L1_error)
-  __pyx_k__60 = __pyx_t_6;
+  __pyx_t_6 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4185, __pyx_L1_error)
+  __pyx_k__64 = __pyx_t_6;
 
-  /* "pywrapfst.pyx":4264
+  /* "pywrapfst.pyx":4282
  * 
  *   @classmethod
  *   def open(cls, *filenames):             # <<<<<<<<<<<<<<
  *     """
  *     FarReader.open(*filenames)
  */
-  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4264, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4282, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4263
+  /* "pywrapfst.pyx":4281
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def open(cls, *filenames):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4263, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_1) < 0) __PYX_ERR(0, 4264, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4281, __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, 4282, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4439
+  /* "pywrapfst.pyx":4444
  * 
  *   @classmethod
  *   def create(cls, filename, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4439, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4444, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4438
+  /* "pywrapfst.pyx":4443
  *     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_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4438, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_2) < 0) __PYX_ERR(0, 4439, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4443, __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, 4444, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4531
+  /* "pywrapfst.pyx":4543
  * 
  * 
  * _fst_error_fatal_old = fst.FLAGS_fst_error_fatal             # <<<<<<<<<<<<<<
  * fst.FLAGS_fst_error_fatal = False
  * 
  */
-  __pyx_t_2 = __Pyx_PyBool_FromLong(FLAGS_fst_error_fatal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4531, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fst_error_fatal_old, __pyx_t_2) < 0) __PYX_ERR(0, 4531, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = __Pyx_PyBool_FromLong(FLAGS_fst_error_fatal); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4543, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_fst_error_fatal_old, __pyx_t_1) < 0) __PYX_ERR(0, 4543, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4532
+  /* "pywrapfst.pyx":4544
  * 
  * _fst_error_fatal_old = fst.FLAGS_fst_error_fatal
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -51556,28 +51349,28 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
  */
   FLAGS_fst_error_fatal = 0;
 
-  /* "pywrapfst.pyx":4535
+  /* "pywrapfst.pyx":4547
  * 
  * 
  * @atexit.register             # <<<<<<<<<<<<<<
  * def _reset_fst_error_fatal():
  *   fst.FLAGS_fst_error_fatal = _fst_error_fatal_old
  */
-  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_atexit); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4535, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_register); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4535, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_atexit); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4547, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_register); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4547, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":4536
+  /* "pywrapfst.pyx":4548
  * 
  * @atexit.register
  * def _reset_fst_error_fatal():             # <<<<<<<<<<<<<<
  *   fst.FLAGS_fst_error_fatal = _fst_error_fatal_old
  * 
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_57_reset_fst_error_fatal, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4536, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_57_reset_fst_error_fatal, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4548, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
     __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
@@ -51589,53 +51382,53 @@ PyMODINIT_FUNC PyInit_pywrapfst(void)
     }
   }
   if (!__pyx_t_4) {
-    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4535, __pyx_L1_error)
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4547, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_GOTREF(__pyx_t_1);
   } else {
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_3)) {
-      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_1};
-      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4535, __pyx_L1_error)
+      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2};
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4547, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     } else
     #endif
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
-      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_1};
-      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4535, __pyx_L1_error)
+      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2};
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4547, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     } else
     #endif
     {
-      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4535, __pyx_L1_error)
+      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4547, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
-      __Pyx_GIVEREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_1);
-      __pyx_t_1 = 0;
-      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4535, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_GIVEREF(__pyx_t_2);
+      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
+      __pyx_t_2 = 0;
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4547, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     }
   }
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reset_fst_error_fatal, __pyx_t_2) < 0) __PYX_ERR(0, 4536, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reset_fst_error_fatal, __pyx_t_1) < 0) __PYX_ERR(0, 4548, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
   /* "pywrapfst.pyx":1
  * #cython: nonecheck=True             # <<<<<<<<<<<<<<
  * # Licensed under the Apache License, Version 2.0 (the "License");
  * # you may not use this file except in compliance with the License.
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_2, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_2, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
   /* "vector.from_py":50
  * 
@@ -53820,24 +53613,24 @@ bad:
 }
 
 /* CIntToPy */
-                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
-    const int neg_one = (int) -1, const_zero = (int) 0;
+                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) {
+    const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0;
     const int is_unsigned = neg_one > const_zero;
     if (is_unsigned) {
-        if (sizeof(int) < sizeof(long)) {
+        if (sizeof(uint32_t) < sizeof(long)) {
             return PyInt_FromLong((long) value);
-        } else if (sizeof(int) <= sizeof(unsigned long)) {
+        } else if (sizeof(uint32_t) <= sizeof(unsigned long)) {
             return PyLong_FromUnsignedLong((unsigned long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) {
+        } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) {
             return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
 #endif
         }
     } else {
-        if (sizeof(int) <= sizeof(long)) {
+        if (sizeof(uint32_t) <= sizeof(long)) {
             return PyInt_FromLong((long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) {
+        } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) {
             return PyLong_FromLongLong((PY_LONG_LONG) value);
 #endif
         }
@@ -53845,30 +53638,30 @@ bad:
     {
         int one = 1; int little = (int)*(unsigned char *)&one;
         unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(int),
+        return _PyLong_FromByteArray(bytes, sizeof(uint32_t),
                                      little, !is_unsigned);
     }
 }
 
 /* CIntToPy */
-                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value) {
-    const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0;
+                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = (int) 0;
     const int is_unsigned = neg_one > const_zero;
     if (is_unsigned) {
-        if (sizeof(int64_t) < sizeof(long)) {
+        if (sizeof(int) < sizeof(long)) {
             return PyInt_FromLong((long) value);
-        } else if (sizeof(int64_t) <= sizeof(unsigned long)) {
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
             return PyLong_FromUnsignedLong((unsigned long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) {
+        } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) {
             return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
 #endif
         }
     } else {
-        if (sizeof(int64_t) <= sizeof(long)) {
+        if (sizeof(int) <= sizeof(long)) {
             return PyInt_FromLong((long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) {
+        } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) {
             return PyLong_FromLongLong((PY_LONG_LONG) value);
 #endif
         }
@@ -53876,30 +53669,30 @@ bad:
     {
         int one = 1; int little = (int)*(unsigned char *)&one;
         unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(int64_t),
+        return _PyLong_FromByteArray(bytes, sizeof(int),
                                      little, !is_unsigned);
     }
 }
 
 /* CIntToPy */
-                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) {
-    const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0;
+                  static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value) {
+    const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0;
     const int is_unsigned = neg_one > const_zero;
     if (is_unsigned) {
-        if (sizeof(uint32_t) < sizeof(long)) {
+        if (sizeof(int64_t) < sizeof(long)) {
             return PyInt_FromLong((long) value);
-        } else if (sizeof(uint32_t) <= sizeof(unsigned long)) {
+        } else if (sizeof(int64_t) <= sizeof(unsigned long)) {
             return PyLong_FromUnsignedLong((unsigned long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) {
+        } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) {
             return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
 #endif
         }
     } else {
-        if (sizeof(uint32_t) <= sizeof(long)) {
+        if (sizeof(int64_t) <= sizeof(long)) {
             return PyInt_FromLong((long) value);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) {
+        } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) {
             return PyLong_FromLongLong((PY_LONG_LONG) value);
 #endif
         }
@@ -53907,7 +53700,7 @@ bad:
     {
         int one = 1; int little = (int)*(unsigned char *)&one;
         unsigned char *bytes = (unsigned char *)&value;
-        return _PyLong_FromByteArray(bytes, sizeof(uint32_t),
+        return _PyLong_FromByteArray(bytes, sizeof(int64_t),
                                      little, !is_unsigned);
     }
 }
index fe0df2d..5d0e019 100644 (file)
@@ -250,7 +250,7 @@ cdef class _Fst(object):
 
   cpdef void write(self, filename) except *
 
-  cpdef string WriteToString(self)
+  cpdef string write_to_string(self)
 
 
 cdef class _MutableFst(_Fst):
@@ -313,7 +313,7 @@ cdef class _MutableFst(_Fst):
 
   cdef void _set_final(self, int64 state, weight=?) except *
 
-  cdef void _set_properties(self, uint64 props, uint64 mask) except *
+  cdef void _set_properties(self, uint64 props, uint64 mask)
 
   cdef void _set_start(self, int64 state) except *
 
index 14d2ab8..74390f0 100644 (file)
@@ -134,11 +134,6 @@ class FstOpError(FstError, RuntimeError):
   pass
 
 
-class FstUnknownWeightTypeError(FstError, ValueError):
-
-  pass
-
-
 ## General helpers.
 
 
@@ -347,8 +342,8 @@ cdef class Weight(object):
     weight_string: A string indicating the underlying weight.
 
   Raises:
-    FstBadWeightError: invalid weight.
-    FstUnknownWeightTypeError: weight type not found.
+    FstArgError: Weight type not found.
+    FstBadWeightError: Invalid weight.
   """
 
   def __repr__(self):
@@ -371,9 +366,9 @@ cdef class Weight(object):
 
   cdef void _check_weight(self) except *:
     if self.type() == b"none":
-      raise FstUnknownWeightTypeError(self.type())
+      raise FstArgError("Weight type not found")
     if self.to_string() == b"BadNumber":
-      raise FstBadWeightError(self.to_string())
+      raise FstBadWeightError("Invalid weight")
 
   cpdef Weight copy(self):
     """
@@ -393,6 +388,8 @@ cdef class Weight(object):
   def Zero(cls, weight_type):
     """
     Weight.Zero(weight_type)
+
+    Constructs semiring zero.
     """
     return _Weight_Zero(weight_type)
 
@@ -400,6 +397,8 @@ cdef class Weight(object):
   def One(cls, weight_type):
     """
     Weight.One(weight_type)
+
+    Constructs semiring One.
     """
     return _Weight_One(weight_type)
 
@@ -407,6 +406,8 @@ cdef class Weight(object):
   def NoWeight(cls, weight_type):
     """
     Weight.NoWeight(weight_type)
+
+    Constructs a non-member weight in the semiring.
     """
     return _Weight_NoWeight(weight_type)
 
@@ -423,6 +424,10 @@ cdef class Weight(object):
     return self._weight.get().ToString()
 
   cpdef string type(self):
+    """type(self)
+
+    Returns a string indicating the weight type.
+    """
     return self._weight.get().Type()
 
 
@@ -443,15 +448,15 @@ def plus(Weight lhs, Weight rhs):
   are not in the same semiring.
 
   Args:
-     lhs: left-hand side Weight.
-     rhs: right-hand side Weight.
+     lhs: Left-hand side Weight.
+     rhs: Right-hand side Weight.
 
   Returns:
     A Weight object.
 
   Raises:
+    FstArgError: Weight type not found (or not in same semiring).
     FstBadWeightError: invalid weight.
-    FstUnknownWeightTypeError: weights are null or not in the same semiring.
   """
   cdef Weight result = _plus(lhs, rhs)
   result._check_weight()
@@ -475,15 +480,15 @@ def times(Weight lhs, Weight rhs):
   are not in the same semiring.
 
   Args:
-     lhs: left-hand side Weight.
-     rhs: right-hand side Weight.
+     lhs: Left-hand side Weight.
+     rhs: Right-hand side Weight.
 
   Returns:
     A Weight object.
 
   Raises:
-    FstBadWeightError: invalid weight.
-    FstUnknownWeightTypeError: weights are null or not in the same semiring.
+    FstArgError: Weight type not found (or not in same semiring).
+    FstBadWeightError: Invalid weight.
   """
   cdef Weight result = _times(lhs, rhs)
   result._check_weight()
@@ -509,15 +514,15 @@ def divide(Weight lhs, Weight rhs):
   are equivalent operations.
 
   Args:
-     lhs: left-hand side Weight.
-     rhs: right-hand side Weight.
+     lhs: Left-hand side Weight.
+     rhs: Right-hand side Weight.
 
   Returns:
     A Weight object.
 
   Raises:
-    FstBadWeightError: invalid weight.
-    FstUnknownWeightTypeError: weights are null or not in the same semiring.
+    FstArgError: Weight type not found (or not in same semiring).
+    FstBadWeightError: Invalid weight.
   """
   cdef Weight result = _divide(lhs, rhs)
   result._check_weight()
@@ -532,7 +537,7 @@ cdef Weight _power(Weight w, size_t n):
 
 def power(Weight w, size_t n):
   """
-  times(lhs, rhs)
+  power(lhs, rhs)
 
   Computes the iterated product of a weight.
 
@@ -544,8 +549,8 @@ def power(Weight w, size_t n):
     A Weight object.
 
   Raises:
-    FstBadWeightError: invalid weight.
-    FstUnknownWeightTypeError: weights are null or not in the same semiring.
+    FstArgError: Weight type not found (or not in same semiring).
+    FstBadWeightError: Invalid weight.
   """
   cdef Weight result = _power(w, n)
   result._check_weight()
@@ -615,7 +620,7 @@ cdef Weight _Weight_Zero(weight_type):
   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
       tostring(weight_type))))
   if result._weight.get().Type() == b"none":
-    raise FstUnknownWeightTypeError(weight_type)
+    raise FstArgError("Weight type not found")
   return result
 
 
@@ -624,7 +629,7 @@ cdef Weight _Weight_One(weight_type):
   result._weight.reset(new fst.WeightClass(
         fst.WeightClass.One(tostring(weight_type))))
   if result._weight.get().Type() == b"none":
-    raise FstUnknownWeightTypeError(weight_type)
+    raise FstArgError("Weight type not found")
   return result
 
 
@@ -674,9 +679,19 @@ cdef class _SymbolTable(object):
     return SymbolTableIterator(self)
 
   cpdef int64 available_key(self):
+    """
+    available_key(self)
+
+    Returns an integer indicating the next available key index in the table.
+    """
     return self._table.AvailableKey()
 
   cpdef string checksum(self):
+    """
+    checksum(self)
+
+    Returns a string indicating the label-agnostic MD5 checksum for the table.
+    """
     return self._table.CheckSum()
 
   cpdef SymbolTable copy(self):
@@ -716,6 +731,34 @@ cdef class _SymbolTable(object):
         raise KeyError(key)
     return result
 
+  cpdef int64 get_nth_key(self, ssize_t pos) except *:
+    """
+    get_nth_key(self, pos)
+
+    Retrieves the integer index of the n-th key in the table.
+
+    Args:
+      pos: The n-th key to retrieve.
+
+    Returns:
+      The integer index of the n-th key.
+
+    Raises:
+      KeyError: index not found.
+    """
+    cdef int64 result = self._table.GetNthKey(pos)
+    if result == -1:
+      raise KeyError(pos)
+    return result
+
+  cpdef string labeled_checksum(self):
+    """
+    labeled_checksum(self)
+
+    Returns a string indicating the label-dependent MD5 checksum for the table.
+    """
+    return self._table.LabeledCheckSum()
+
   cpdef bool member(self, key):
     """
     member(self, key)
@@ -724,7 +767,7 @@ cdef class _SymbolTable(object):
 
     This method returns a boolean indicating whether the given symbol or index
     is present in the table. If one intends to perform subsequent lookup, it is
-    much better to simply call the find method, catching the KeyError.
+    better to simply call the find method, catching the KeyError.
 
     Args:
       key: Either a string or an index.
@@ -740,33 +783,20 @@ cdef class _SymbolTable(object):
   def __contains__(self, key):
     return self.member(key)
 
-  cpdef int64 get_nth_key(self, ssize_t pos) except *:
+  cpdef string name(self):
     """
-    get_nth_key(self, pos)
-
-    Retrieves the integer index of the n-th key in the table.
-
-    Args:
-      pos: The n-th key to retrieve.
+    name(self)
 
-    Returns:
-      The integer index of the n-th key.
-
-    Raises:
-      KeyError: index not found.
+    Returns the symbol table's name.
     """
-    cdef int64 result = self._table.GetNthKey(pos)
-    if result == -1:
-      raise KeyError(pos)
-    return result
-
-  cpdef string labeled_checksum(self):
-    return self._table.LabeledCheckSum()
-
-  cpdef string name(self):
     return self._table.Name()
 
   cpdef size_t num_symbols(self):
+    """
+    num_symbols(self)
+
+    Returns the number of symbols in the symbol table.
+    """
     return self._table.NumSymbols()
 
   cpdef void write(self, filename) except *:
@@ -899,15 +929,6 @@ cdef class _MutableFstSymbolTable(_MutableSymbolTable):
   (No constructor.)
 
   Mutable SymbolTable assigned to an FST.
-
-  Attributes:
-    available_key: An integer indicating the next available key index in the
-        table.
-    checksum: A string indicating the label-agnostic MD5 checksum for the table.
-    labeled_checksum: A string indicating the label-dependent MD5 checksum for
-        the table.
-    name: A string indicating the table's name.
-    num_symbols: An integer indicating the number of symbols in the table.
   """
 
   def __repr__(self):
@@ -922,21 +943,13 @@ cdef class SymbolTable(_MutableSymbolTable):
   Mutable SymbolTable class.
 
   This class wraps the library SymbolTable and exposes both const (i.e.,
-  access) and non-const (i.e., mutation) methods of wrapped object. Unlike
-  other classes in the hierarchy, it has a working constructor and can be used
-  to programmatically construct a SymbolTable in memory.
+  access) and non-const (i.e., mutation) methods of wrapped object.
 
-  Args:
-    name: A string indicating the table's name
+  Unlike other classes in the hierarchy, it has a working constructor and can be
+  used to programmatically construct a SymbolTable in memory.
 
-  Attributes:
-    available_key: An integer indicating the next available key index in the
-        table.
-    checksum: A string indicating the label-agnostic MD5 checksum for the table.
-    labeled_checksum: A string indicating the label-dependent MD5 checksum for
-        the table.
-    name: A string indicating the table's name.
-    num_symbols: An integer indicating the number of symbols in the table.
+  Args:
+    name: An optional string indicating the table's name.
   """
 
   def __repr__(self):
@@ -1032,6 +1045,7 @@ cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(
   result._encoder = encoder
   return result
 
+
 cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
                                           shared_ptr[fst.FstClass] ifst):
   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
@@ -1109,10 +1123,7 @@ cdef class SymbolTableIterator(object):
   """
   SymbolTableIterator(syms)
 
-  This class is used for iterating over a symbol table using a Pythonic API. It
-  also supports the C++ API methods, but most users should simply place a
-  SymbolTable in an iteration context and take advantage of the Pythonic API
-  that provides.
+  This class is used for iterating over a symbol table.
   """
 
   def __repr__(self):
@@ -1140,9 +1151,6 @@ cdef class SymbolTableIterator(object):
 
     Indicates whether the iterator is exhausted or not.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       True if the iterator is exhausted, False otherwise.
     """
@@ -1153,9 +1161,6 @@ cdef class SymbolTableIterator(object):
     next(self)
 
     Advances the iterator.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._siter.get().Next()
 
@@ -1164,9 +1169,6 @@ cdef class SymbolTableIterator(object):
     reset(self)
 
     Resets the iterator to the initial position.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._siter.get().Reset()
 
@@ -1178,9 +1180,6 @@ cdef class SymbolTableIterator(object):
 
     This method returns the current symbol string at this point in the table.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       A symbol string.
     """
@@ -1192,9 +1191,6 @@ cdef class SymbolTableIterator(object):
 
     Returns the current integer index of the symbol.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       An integer index.
     """
@@ -1241,6 +1237,11 @@ cdef class EncodeMapper(object):
       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
 
   cpdef string arc_type(self):
+    """
+    arc_type(self)
+
+    Returns a string indicating the arc type.
+    """
     return self._encoder.get().ArcType()
 
   # Python's equivalent to operator().
@@ -1264,19 +1265,36 @@ cdef class EncodeMapper(object):
     return _init_Arc(self._encoder.get().__call__(deref(arc._arc)))
 
   cpdef uint32 flags(self):
+    """
+    flags(self)
+
+    Returns the encoder's flags.
+    """
     return self._encoder.get().Flags()
 
   cpdef _EncodeMapperSymbolTable input_symbols(self):
-    if self._encoder.get().InputSymbols() == NULL:
+    """
+    input_symbols(self)
+
+    Returns the encoder's input symbol table, or None if none is present.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+        self._encoder.get().InputSymbols())
+    if syms == NULL:
       return
-    return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
-        self._encoder.get().InputSymbols()), self._encoder)
+    return _init_EncodeMapperSymbolTable(syms, self._encoder)
 
   cpdef _EncodeMapperSymbolTable output_symbols(self):
-    if self._encoder.get().OutputSymbols() == NULL:
+    """
+    output_symbols(self)
+
+    Returns the encoder's output symbol table, or None if none is present.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+        self._encoder.get().OutputSymbols())
+    if syms == NULL:
       return
-    return _init_EncodeMapperSymbolTable(const_cast[SymbolTable_ptr](
-        self._encoder.get().OutputSymbols()), self._encoder)
+    return _init_EncodeMapperSymbolTable(syms, self._encoder)
 
   cpdef uint64 properties(self, uint64 mask):
     """
@@ -1284,9 +1302,7 @@ cdef class EncodeMapper(object):
 
     Provides property bits.
 
-    This method provides user access to the properties attributes for the
-    encoder. The resulting value is a long integer, but when it is cast to a
-    boolean, it represents whether or not the FST has the `mask` property.
+    This method provides user access to the properties of the encoder.
 
     Args:
       mask: The property mask to be compared to the encoder's properties.
@@ -1300,7 +1316,7 @@ cdef class EncodeMapper(object):
     """
     set_input_symbols(self, syms)
 
-    Sets the input symbol table.
+    Sets the encoder's input symbol table.
 
     Args:
       syms: A SymbolTable.
@@ -1313,7 +1329,7 @@ cdef class EncodeMapper(object):
     """
     set_output_symbols(self, syms)
 
-    Sets the output symbol table.
+    Sets the encoder's output symbol table.
 
     Args:
       syms: A SymbolTable.
@@ -1323,6 +1339,11 @@ cdef class EncodeMapper(object):
     self._encoder.get().SetOutputSymbols(syms._table)
 
   cpdef string weight_type(self):
+    """
+    weight_type(self)
+
+    Returns a string indicating the weight type.
+    """
     return self._encoder.get().WeightType()
 
 
@@ -1391,19 +1412,24 @@ cdef class _Fst(object):
         fst.kWeighted)
 
   cpdef string arc_type(self):
+    """
+    arc_type(self)
+
+    Returns a string indicating the arc type.
+    """
     return self._fst.get().ArcType()
 
   cpdef ArcIterator arcs(self, int64 state):
     """
     arcs(self, state)
 
-    Returns an iterator over arcs leaving some state=.
+    Returns an iterator over arcs leaving the specified state.
 
     Args:
-      s: The source state ID.
+      state: The source state ID.
 
     Returns:
-      An ArcIterator over arcs leaving state `state`.
+      An ArcIterator.
 
     See also: `mutable_arcs`, `states`.
     """
@@ -1465,13 +1491,11 @@ cdef class _Fst(object):
       float_format: One of: 'e', 'f' or 'g'.
       show_weight_one: Should weights equivalent to semiring One be printed?
 
-    For more information about the rendering options, see `man dot`.
-
     See also: `text`.
     """
     cdef string filename_string = tostring(filename)
     cdef unique_ptr[ofstream] ostrm
-    ostrm.reset(new ofstream(filename_string.c_str()))
+    ostrm.reset(new ofstream(filename_string))
     cdef fst.SymbolTable *ssymbols_ptr = NULL
     if ssymbols is not None:
       ssymbols_ptr = ssymbols._table
@@ -1505,13 +1529,26 @@ cdef class _Fst(object):
     return weight
 
   cpdef string fst_type(self):
+    """
+    fst_type(self)
+
+    Returns a string indicating the FST type.
+    """
     return self._fst.get().FstType()
 
   cpdef _FstSymbolTable input_symbols(self):
-    if self._fst.get().InputSymbols() == NULL:
+    """
+    input_symbols(self)
+
+    Returns the FST's input symbol table, or None if none is present.
+
+    See also: `input_symbols`.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+      self._fst.get().InputSymbols())
+    if syms == NULL:
       return
-    return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
-        self._fst.get().InputSymbols()), self._fst)
+    return _init_FstSymbolTable(syms, self._fst)
 
   cpdef size_t num_arcs(self, int64 state) except *:
     """
@@ -1580,10 +1617,18 @@ cdef class _Fst(object):
     return result
 
   cpdef _FstSymbolTable output_symbols(self):
-    if self._fst.get().OutputSymbols() == NULL:
+    """
+    output_symbols(self)
+
+    Returns the FST's output symbol table, or None if none is present.
+
+    See also: `input_symbols`.
+    """
+    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
+      self._fst.get().OutputSymbols())
+    if syms == NULL:
       return
-    return _init_FstSymbolTable(const_cast[SymbolTable_ptr](
-        self._fst.get().OutputSymbols()), self._fst)
+    return _init_FstSymbolTable(syms, self._fst)
 
   cpdef uint64 properties(self, uint64 mask, bool test):
     """
@@ -1606,6 +1651,11 @@ cdef class _Fst(object):
     return self._fst.get().Properties(mask, test)
 
   cpdef int64 start(self):
+    """
+    start(self)
+
+    Returns the start state.
+    """
     return self._fst.get().Start()
 
   cpdef StateIterator states(self):
@@ -1697,7 +1747,17 @@ cdef class _Fst(object):
     if not self._fst.get().Write(tostring(filename)):
       raise FstIOError("Write failed: {!r}".format(filename))
 
-  cpdef string WriteToString(self):
+  cpdef string write_to_string(self):
+    """
+    write_to_string(self)
+
+    Serializes FST to a string.
+
+    Returns:
+      A string.
+
+    See also: `read_from_string`.
+    """
     return self._fst.get().WriteToString()
 
 
@@ -2030,32 +2090,46 @@ cdef class _MutableFst(_Fst):
     """
     mutable_arcs(self, state)
 
-    Returns a iterator over arcs leaving some state which supports
-    arc mutation.
+    Returns a mutable iterator over arcs leaving the specified state.
 
     Args:
-      s: The source state ID.
+      state: The source state ID.
 
     Returns:
-      A MutableArcIterator over arcs leaving state `s`.
+      A MutableArcIterator.
 
     See also: `arcs`, `states`.
     """
     return MutableArcIterator(self, state)
 
   def mutable_input_symbols(self):
+    """
+    mutable_input_symbols(self)
+
+    Returns the FST's (mutable) input symbol table, or None if none is present.
+    """
     cdef fst.SymbolTable *tst = self._mfst.get().MutableInputSymbols()
     if tst == NULL:
       return
     return _init_MutableFstSymbolTable(tst, self._mfst)
 
   def mutable_output_symbols(self):
+    """
+    mutable_output_symbols(self)
+
+    Returns the FST's (mutable) output symbol table, or None if none is present.
+    """
     cdef fst.SymbolTable *tst = self._mfst.get().MutableOutputSymbols()
     if tst == NULL:
       return
     return _init_MutableFstSymbolTable(tst, self._mfst)
 
   cpdef int64 num_states(self):
+    """
+    num_states(self)
+
+    Returns the number of states.
+    """
     return self._mfst.get().NumStates()
 
   cdef void _project(self, bool project_output=False) except *:
@@ -2414,7 +2488,7 @@ cdef class _MutableFst(_Fst):
     """
     set_final(self, state, weight)
 
-    Sets a state to be final with a fixed cost.
+    Sets the final weight for a state.
 
     Args:
       state: The integer index of a state.
@@ -2430,51 +2504,6 @@ cdef class _MutableFst(_Fst):
     self._set_final(state, weight)
     return self
 
-  cdef void _set_properties(self, uint64 props, uint64 mask) except *:
-    self._mfst.get().SetProperties(props, mask)
-
-  def set_properties(self, uint64 props, uint64 mask):
-    """
-    set_properties(self, props, mask)
-
-    Sets the properties bits.
-
-    Args:
-      props: The properties to be set.
-      mask: A mask to be applied to the `props` argument before
-        setting the FST's properties.
-
-    Returns:
-      self.
-    """
-    self._set_properties(props, mask)
-    return self
-
-  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()
-
-  def set_start(self, int64 state):
-    """
-    set_start(self, state)
-
-    Sets the initial state.
-
-    Args:
-      state: The integer index of a state.
-
-    Returns:
-      self.
-
-    Raises:
-      FstIndexError: State index out of range.
-
-    See also: `set_final`.
-    """
-    self._set_start(state)
-    return self
-
   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
     if syms is None:
       self._mfst.get().SetInputSymbols(NULL)
@@ -2527,6 +2556,51 @@ cdef class _MutableFst(_Fst):
     self._set_output_symbols(syms)
     return self
 
+  cdef void _set_properties(self, uint64 props, uint64 mask):
+    self._mfst.get().SetProperties(props, mask)
+
+  def set_properties(self, uint64 props, uint64 mask):
+    """
+    set_properties(self, props, mask)
+
+    Sets the properties bits.
+
+    Args:
+      props: The properties to be set.
+      mask: A mask to be applied to the `props` argument before setting the
+          FST's properties.
+
+    Returns:
+      self.
+    """
+    self._set_properties(props, mask)
+    return self
+
+  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()
+
+  def set_start(self, int64 state):
+    """
+    set_start(self, state)
+
+    Sets a state to be the initial state state.
+
+    Args:
+      state: The integer index of a state.
+
+    Returns:
+      self.
+
+    Raises:
+      FstIndexError: State index out of range.
+
+    See also: `set_final`.
+    """
+    self._set_start(state)
+    return self
+
   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()):
@@ -2644,6 +2718,7 @@ cdef _Fst _read_Fst(filename, fst_type=None):
         raise FstOpError("Conversion to {!r} failed.".format(fst_type))
   return _init_XFst(tfst)
 
+
 cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
   ofst = fst.FstClass.ReadFromString(fst_string)
   if fst_type is not None:
@@ -2654,6 +2729,7 @@ cdef _Fst _deserialize_Fst(fst_string, fst_type=None):
         raise FstOpError("Conversion to {!r} failed.".format(fst_type))
   return _init_XFst(ofst)
 
+
 class Fst(object):
 
    """
@@ -2700,10 +2776,10 @@ class Fst(object):
      """
      read_from_string(fst_string, fst_type=None)
 
-     Reads an FST from a string.
+     Reads an FST from a serialized string.
 
      Args:
-       fst_string: The string containing the serialized Fst.
+       fst_string: The string containing the serialized FST.
        fst_type: A string indicating the FST type to convert to; no conversion
          is performed if omitted or if the FST is already of the desired type.
 
@@ -2713,9 +2789,12 @@ class Fst(object):
      Raises:
        FstIOError: Read failed.
        FstOpError: Read-time conversion failed.
+
+     See also: `write_to_string`.
      """
      return _deserialize_Fst(fst_string, fst_type)
 
+
 ## FST properties.
 
 
@@ -2779,6 +2858,26 @@ NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
 FST_PROPERTIES = fst.kFstProperties
 
 
+## Arc iterator properties.
+
+
+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
+ARC_VALUE_FLAGS = fst.kArcValueFlags
+ARC_FLAGS = fst.kArcFlags
+
+
+## EncodeMapper properties.
+
+
+ENCODE_LABELS = fst.kEncodeLabels
+ENCODE_WEIGHTS = fst.kEncodeWeights
+ENCODE_FLAGS = fst.kEncodeFlags
+
+
 ## Arc, ArcIterator, and MutableArcIterator.
 
 
@@ -2856,8 +2955,6 @@ cdef class ArcIterator(object):
   ArcIterator(ifst, state)
 
   This class is used for iterating over the arcs leaving some state of an FST.
-  It supports the full C++ API, but most users should just call the `arcs`
-  method of an FST object and take advantage of the Pythonic API.
   """
 
   def __repr__(self):
@@ -2888,9 +2985,6 @@ cdef class ArcIterator(object):
 
     Indicates whether the iterator is exhausted or not.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       True if the iterator is exhausted, False otherwise.
     """
@@ -2902,9 +2996,6 @@ cdef class ArcIterator(object):
 
     Returns the current iterator behavioral flags.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       The current iterator behavioral flags as an integer.
     """
@@ -2915,21 +3006,15 @@ cdef class ArcIterator(object):
     next(self)
 
     Advances the iterator.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._aiter.get().Next()
 
   cpdef size_t position(self):
     """
-    next(self)
+    position(self)
 
     Returns the position of the iterator.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       The iterator's position, expressed as an integer.
     """
@@ -2940,9 +3025,6 @@ cdef class ArcIterator(object):
     reset(self)
 
     Resets the iterator to the initial position.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._aiter.get().Reset()
 
@@ -2952,9 +3034,6 @@ cdef class ArcIterator(object):
 
     Advance the iterator to a new position.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       a: The position to seek to.
     """
@@ -2966,9 +3045,6 @@ cdef class ArcIterator(object):
 
     Sets the current iterator behavioral flags.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       flags: The properties to be set.
       mask: A mask to be applied to the `flags` argument before setting them.
@@ -2979,10 +3055,7 @@ cdef class ArcIterator(object):
     """
     value(self)
 
-    Returns the current arc, represented as a tuple.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
+    Returns the current arc.
     """
     return _init_Arc(self._aiter.get().Value())
 
@@ -2993,9 +3066,7 @@ cdef class MutableArcIterator(object):
   MutableArcIterator(ifst, state)
 
   This class is used for iterating over the arcs leaving some state of an FST,
-  also permitting mutation of the current arc. It supports the full C++ API,
-  but most users should just call the `mutable_arcs` method of an FST object
-  and take advantage of the Pythonic API.
+  also permitting mutation of the current arc.
   """
 
   def __repr__(self):
@@ -3008,27 +3079,12 @@ cdef class MutableArcIterator(object):
     self._mfst = ifst._mfst
     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))
 
-  # This just registers this class as a possible iterator.
-  def __iter__(self):
-    return self
-
-  # Magic method used to get a Pythonic API out of the C++ API.
-  def __next__(self):
-    if self.done():
-      raise StopIteration
-    result = self.value()
-    self.next()
-    return result
-
   cpdef bool done(self):
     """
     done(self)
 
     Indicates whether the iterator is exhausted or not.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       True if the iterator is exhausted, False otherwise.
     """
@@ -3040,9 +3096,6 @@ cdef class MutableArcIterator(object):
 
     Returns the current iterator behavioral flags.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       The current iterator behavioral flags as an integer.
     """
@@ -3053,21 +3106,15 @@ cdef class MutableArcIterator(object):
     next(self)
 
     Advances the iterator.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._aiter.get().Next()
 
   cpdef size_t position(self):
     """
-    next(self)
+    position(self)
 
     Returns the position of the iterator.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       The iterator's position, expressed as an integer.
     """
@@ -3078,9 +3125,6 @@ cdef class MutableArcIterator(object):
     reset(self)
 
     Resets the iterator to the initial position.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._aiter.get().Reset()
 
@@ -3090,9 +3134,6 @@ cdef class MutableArcIterator(object):
 
     Advance the iterator to a new position.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       a: The position to seek to.
     """
@@ -3104,9 +3145,6 @@ cdef class MutableArcIterator(object):
 
     Sets the current iterator behavioral flags.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       flags: The properties to be set.
       mask: A mask to be applied to the `flags` argument before setting them.
@@ -3128,10 +3166,7 @@ cdef class MutableArcIterator(object):
     """
     value(self)
 
-    Returns the current arc, represented as a tuple.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
+    Returns the current arc.
     """
     return _init_Arc(self._aiter.get().Value())
 
@@ -3144,9 +3179,7 @@ cdef class StateIterator(object):
   """
   StateIterator(ifst)
 
-  This class is used for iterating over the states in an FST. It supports the
-  full C++ API, but most users should just place an FST argument in an
-  iteration context and take advantage of the Pythonic API.
+  This class is used for iterating over the states in an FST.
   """
 
   def __repr__(self):
@@ -3175,9 +3208,6 @@ cdef class StateIterator(object):
 
     Indicates whether the iterator is exhausted or not.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       True if the iterator is exhausted, False otherwise.
     """
@@ -3188,9 +3218,6 @@ cdef class StateIterator(object):
     next(self)
 
     Advances the iterator.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._siter.get().Next()
 
@@ -3199,9 +3226,6 @@ cdef class StateIterator(object):
     reset(self)
 
     Resets the iterator to the initial position.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._siter.get().Reset()
 
@@ -3210,9 +3234,6 @@ cdef class StateIterator(object):
     value(self)
 
     Returns the current state index.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     return self._siter.get().Value()
 
@@ -3301,7 +3322,7 @@ cpdef _MutableFst compose(_Fst ifst1,
     connect: Should output be trimmed?
 
   Returns:
-    A composed FST.
+    An FST.
 
   See also: `arcsort`.
   """
@@ -3313,16 +3334,16 @@ cpdef _MutableFst compose(_Fst ifst1,
   return _init_MutableFst(tfst)
 
 
-cpdef _Fst convert(_Fst ifst, fst_type=b""):
+cpdef _Fst convert(_Fst ifst, fst_type=None):
   """
-  convert(ifst, fst_type="")
+  convert(ifst, fst_type=None)
 
   Constructively converts an FST to a new internal representation.
 
   Args:
     ifst: The input FST.
     fst_type: A string indicating the FST type to convert to, or None if
-      no conversion is desired.
+        no conversion is desired.
 
   Returns:
     An equivalent Fst converted to the desired FST type.
@@ -3330,8 +3351,8 @@ cpdef _Fst convert(_Fst ifst, fst_type=b""):
   Raises:
     FstOpError: Conversion failed.
   """
-  cdef FstClass_ptr tfst = new fst.FstClass(deref(ifst._fst))
-  tfst = fst.Convert(deref(ifst._fst), tostring(fst_type))
+  cdef string fst_type_string = "" if fst_type is None else tostring(fst_type)
+  cdef FstClass_ptr tfst = fst.Convert(deref(ifst._fst), fst_type_string)
   # Script-land Convert returns the null pointer to signal failure.
   if tfst == NULL:
     raise FstOpError("Conversion to {!r} failed".format(fst_type))
@@ -3419,7 +3440,7 @@ cpdef _MutableFst difference(_Fst ifst1,
     connect: Should the output FST be trimmed?
 
   Returns:
-    An FST representing the difference of the two input FSTs.
+    An FST representing the difference of the FSTs.
   """
   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())
   cdef unique_ptr[fst.ComposeOptions] opts
@@ -3515,7 +3536,7 @@ cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
     delta: Comparison/quantization delta.
 
   Returns:
-    True if the two transducers satisfy the above condition, else False.
+    True if the FSTs satisfy the above condition, else False.
 
   See also: `equivalent`, `isomorphic`, `randequivalent`.
   """
@@ -3538,7 +3559,7 @@ cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:
     delta: Comparison/quantization delta.
 
   Returns:
-    True if the two transducers satisfy the above condition, else False.
+    True if the FSTs satisfy the above condition, else False.
 
   Raises:
     FstOpError: Equivalence test encountered error.
@@ -3575,7 +3596,7 @@ cpdef _MutableFst intersect(_Fst ifst1,
     connect: Should output be trimmed?
 
   Returns:
-    An equivalent epsilon-normalized FST.
+    An intersected FST.
   """
   cdef VectorFstClass_ptr tfst = new fst.VectorFstClass(ifst1.arc_type())
   cdef unique_ptr[fst.ComposeOptions] opts
@@ -3783,7 +3804,7 @@ cpdef _MutableFst randgen(_Fst ifst,
         `weighted` is False)?
 
   Returns:
-    An Fst containing one or more random paths.
+    An FST containing one or more random paths.
 
   See also: `randequivalent`.
   """
@@ -4229,10 +4250,7 @@ cdef class FarReader(object):
 
   This class is used to read a FAR from disk. FARs contain one or more FSTs (of
   the same arc type) indexed by a unique string key. To construct a FarReader
-  object, use the `open` class method. FSTs can be accessed from a FAR using the
-  familiar C++ API methods, but a user who wishes to access all FSTs in random
-  order should simply place a FarReader in an iteration context and take
-  advantage of the Pythonic API that provides.
+  object, use the `open` class method.
 
   Attributes:
     arc_type: A string indicating the arc type.
@@ -4287,6 +4305,11 @@ cdef class FarReader(object):
     return (k, f)
 
   cpdef string arc_type(self):
+    """
+    arc_type(self)
+
+    Returns a string indicating the arc type.
+    """
     return self._reader.get().ArcType()
 
   cpdef bool done(self):
@@ -4295,9 +4318,6 @@ cdef class FarReader(object):
 
     Indicates whether the iterator is exhausted or not.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       True if the iterator is exhausted, False otherwise.
     """
@@ -4324,9 +4344,6 @@ cdef class FarReader(object):
     Sets the current position to the first entry greater than or equal to the
     key (a string) and indicates whether or not a match was found.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       key: A string key.
 
@@ -4341,9 +4358,6 @@ cdef class FarReader(object):
 
     Returns the FST at the current position.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       A copy of the FST at the current position.
     """
@@ -4357,9 +4371,6 @@ cdef class FarReader(object):
 
     Returns the string key at the current position.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Returns:
       The string key at the current position.
     """
@@ -4370,9 +4381,6 @@ cdef class FarReader(object):
     next(self)
 
     Advances the iterator.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._reader.get().Next()
 
@@ -4381,9 +4389,6 @@ cdef class FarReader(object):
     reset(self)
 
     Resets the iterator to the initial position.
-
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
     """
     self._reader.get().Reset()
 
@@ -4466,9 +4471,6 @@ cdef class FarWriter(object):
     This method adds an FST to the FAR which can be retrieved with the
     specified string key.
 
-    This method is provided for compatibility with the C++ API only; most users
-    should use the Pythonic API.
-
     Args:
       key: The string used to key the input FST.
       ifst: The FST to write to the FAR.
@@ -4486,6 +4488,11 @@ cdef class FarWriter(object):
       raise FstArgError("Key out of order")
 
   cpdef string arc_type(self):
+    """
+    arc_type(self)
+
+    Returns a string indicating the arc type.
+    """
     return self._writer.get().ArcType()
 
   cpdef bool error(self):
@@ -4500,6 +4507,11 @@ cdef class FarWriter(object):
     return self._writer.get().Error()
 
   cpdef string far_type(self):
+    """
+    far_type(self)
+
+    Returns a string indicating the FAR type.
+    """
     return fst.GetFarTypeString(self._writer.get().Type())
 
   # Dictionary-like assignment.
index 7c4a2e6..f257b43 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 7:0:0 -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 8:0:0 -lm $(DL_LIBS)
 libfstspecial_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 phi_fst_la_SOURCES = phi-fst.cc
index 103911a..0d83f8d 100644 (file)
@@ -378,7 +378,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(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 7:0:0 -lm $(DL_LIBS)
+libfstspecial_la_LDFLAGS = -version-info 8: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 bc54e18..6a3664d 100644 (file)
@@ -800,7 +800,7 @@ class ToGallicMapper {
   using FromArc = A;
   using ToArc = GallicArc<A, G>;
 
-  using SW = StringWeight<typename A::Label, GALLIC_STRING_TYPE(G)>;
+  using SW = StringWeight<typename A::Label, GallicStringType(G)>;
   using AW = typename FromArc::Weight;
   using GW = typename ToArc::Weight;
 
@@ -893,10 +893,10 @@ class FromGallicMapper {
   template <GallicType GT>
   static bool Extract(const GallicWeight<Label, AW, GT> &gallic_weight,
                       typename A::Weight *weight, typename A::Label *label) {
-    const StringWeight<Label, GALLIC_STRING_TYPE(GT)> &w1 =
-        gallic_weight.Value1();
+    using GW = StringWeight<Label, GallicStringType(GT)>;
+    const GW &w1 = gallic_weight.Value1();
     const AW &w2 = gallic_weight.Value2();
-    StringWeightIterator<Label, GALLIC_STRING_TYPE(GT)> iter1(w1);
+    typename GW::Iterator iter1(w1);
     const Label l = w1.Size() == 1 ? iter1.Value() : 0;
     if (l == kStringInfinity || l == kStringBad || w1.Size() > 1) return false;
     *label = l;
@@ -930,7 +930,7 @@ class GallicToNewSymbolsMapper {
   using StateId = typename ToArc::StateId;
   using AW = typename ToArc::Weight;
   using GW = typename FromArc::Weight;
-  using SW = StringWeight<Label, GALLIC_STRING_TYPE(G)>;
+  using SW = StringWeight<Label, GallicStringType(G)>;
 
   explicit GallicToNewSymbolsMapper(MutableFst<ToArc> *fst)
       : fst_(fst),
@@ -970,7 +970,7 @@ class GallicToNewSymbolsMapper {
       } else {
         l = ++lmax_;
         insert_result.first->second = l;
-        StringWeightIterator<Label, GALLIC_STRING_TYPE(G)> iter1(w1);
+        StringWeightIterator<SW> iter1(w1);
         StateId n;
         string s;
         for (size_t i = 0, p = state_; i < w1.Size();
index 425ca52..376487b 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef FST_LIB_ARC_H_
 #define FST_LIB_ARC_H_
 
+#include <climits>
 #include <string>
 #include <utility>
 
@@ -43,9 +44,9 @@ struct ArcTpl {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static const string type =
-        (Weight::Type() == "tropical") ? "standard" : Weight::Type();
-    return type;
+    static const string *const type =
+        new string(Weight::Type() == "tropical" ? "standard" : Weight::Type());
+    return *type;
   }
 };
 
@@ -78,11 +79,12 @@ struct StringArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static const string type =
-        S == STRING_LEFT ? "left_standard_string"
-                         : (S == STRING_RIGHT ? "right_standard_string"
-                                              : "restricted_standard_string");
-    return type;
+    static const string *const type =
+        new string(S == STRING_LEFT
+                       ? "left_standard_string"
+                       : (S == STRING_RIGHT ? "right_standard_string"
+                                            : "restricted_standard_string"));
+    return *type;
   }
 };
 
@@ -113,16 +115,18 @@ struct GallicArc {
         nextstate(arc.nextstate) {}
 
   static const string &Type() {
-    static const string type =
-        (G == GALLIC_LEFT
-             ? "left_gallic_"
-             : (G == GALLIC_RIGHT
-                    ? "right_gallic_"
-                    : (G == GALLIC_RESTRICT
-                           ? "restricted_gallic_"
-                           : (G == GALLIC_MIN ? "min_gallic_" : "gallic_")))) +
-        Arc::Type();
-    return type;
+    static const string *const type =
+        new string(
+            (G == GALLIC_LEFT
+                 ? "left_gallic_"
+                 : (G == GALLIC_RIGHT
+                        ? "right_gallic_"
+                        : (G == GALLIC_RESTRICT
+                               ? "restricted_gallic_"
+                               : (G == GALLIC_MIN
+                                      ? "min_gallic_" : "gallic_")))) +
+            Arc::Type());
+    return *type;
   }
 };
 
@@ -149,8 +153,8 @@ struct ReverseArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static const string type = "reverse_" + Arc::Type();
-    return type;
+    static const string *const type = new string("reverse_" + Arc::Type());
+    return *type;
   }
 };
 
@@ -175,8 +179,8 @@ struct LexicographicArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static const string type = Weight::Type();
-    return type;
+    static const string *const type = new string(Weight::Type());
+    return *type;
   }
 };
 
@@ -201,8 +205,8 @@ struct ProductArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static const string type = Weight::Type();
-    return type;
+    static const string *const type = new string(Weight::Type());
+    return *type;
   }
 };
 
@@ -230,12 +234,9 @@ struct PowerArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static string type;
-    if (!type.empty()) return type;
-    string power;
-    Int64ToStr(N, &power);
-    type = Arc::Type() + "_^" + power;
-    return type;
+    static string *const type =
+        new string(Arc::Type() + "_^" + std::to_string(N));
+    return *type;
   }
 };
 
@@ -262,15 +263,14 @@ struct SparsePowerArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static string type;
-    if (!type.empty()) return type;
-    type = Arc::Type() + "_^n";
-    if (sizeof(K) != sizeof(uint32)) {
-      string size;
-      Int64ToStr(8 * sizeof(K), &size);
-      type += "_" + size;
-    }
-    return type;
+    static string *const type = [] {
+      string type = Arc::Type() + "_^n";
+      if (sizeof(K) != sizeof(uint32)) {
+        type += "_" + std::to_string(CHAR_BIT * sizeof(K));
+      }
+      return new string(type);
+    }();
+    return *type;
   }
 };
 
@@ -299,10 +299,9 @@ struct ExpectationArc {
         nextstate(nextstate) {}
 
   static const string &Type() {
-    static string type;
-    if (!type.empty()) return type;
-    type = "expectation_" + Arc::Type() + "_" + X2::Type();
-    return type;
+    static string *const type =
+        new string("expectation_" + Arc::Type() + "_" + X2::Type());
+    return *type;
   }
 };
 
index ed993e9..8c528c0 100644 (file)
@@ -1216,7 +1216,7 @@ class CacheMutableArcIterator
 
   void SetValue(const Arc &arc) final { state_->SetArc(arc, i_); }
 
-  constexpr uint32 Flags() const final { return kArcValueFlags; }
+  uint32 Flags() const final { return kArcValueFlags; }
 
   void SetFlags(uint32, uint32) final {}
 
index 38a6ab6..3149a85 100644 (file)
@@ -7,7 +7,10 @@
 #ifndef FST_LIB_COMPACT_FST_H_
 #define FST_LIB_COMPACT_FST_H_
 
+#include <climits>
 #include <iterator>
+#include <memory>
+#include <tuple>
 #include <utility>
 #include <vector>
 
@@ -32,8 +35,58 @@ struct CompactFstOptions : public CacheOptions {
   explicit CompactFstOptions(const CacheOptions &opts) : CacheOptions(opts) {}
 };
 
-// The Compactor class determines how arcs and final weights are compacted and
-// expanded.
+// New upcoming (Fst) Compactor interface - currently used internally
+// by CompactFstImpl.
+//
+// class Compactor {
+//  public:
+//   // Constructor from the Fst to be compacted.
+//   Compactor(const Fst<Arc> &fst, ...);
+//   // Copy constructor
+//   Compactor(const Compactor &compactor, bool safe = false)
+//   // Default constructor (optional, see comment below).
+//   Compactor();
+//
+//   // Returns the start state, number of states, and total number of arcs
+//   // of the compacted Fst
+//   StateId Start() const;
+//   StateId NumStates() const;
+//   size_t NumArcs() const;
+//
+//   // Accessor class for state attributes.
+//   class State {
+//    public:
+//     State();  // Required, corresponds to kNoStateId.
+//     State(const Compactor *c, StateId);  // Accessor for StateId 's'.
+//     StateId GetStateId() const;
+//     Weight Final() const;
+//     size_t NumArcs() const;
+//     Arc GetArc(size_t i) const;
+//   };
+//
+//   // Modifies 'state' accessor to provide access to state id 's'.
+//   void SetState(StateId s, State *state);
+//   // Tests whether 'fst' can be compacted by this compactor.
+//   bool IsCompatible(const Fst<A> &fst) const;
+//   // Return the properties that are always true for an fst
+//   // compacted using this compactor
+//   uint64 Properties() const;
+//   // Return a string identifying the type of compactor.
+//   static const string &Type();
+//   // Return true if an error has occured.
+//   bool Error() const;
+//   // Writes a compactor to a file.
+//   bool Write(std::ostream &strm, const FstWriteOptions &opts) const;
+//   // Reads a compactor from a file.
+//   static Compactor*Read(std::istream &strm, const FstReadOptions &opts,
+//                         const FstHeader &hdr);
+// };
+//
+
+// Old (Arc) Compactor Interface:
+//
+// The ArcCompactor class determines how arcs and final weights are compacted
+// and expanded.
 //
 // Final weights are treated as transitions to the superfinal state, i.e.,
 // ilabel = olabel = kNoLabel and nextstate = kNoStateId.
@@ -51,7 +104,7 @@ struct CompactFstOptions : public CacheOptions {
 //
 // Interface:
 //
-// class Compactor {
+// class ArcCompactor {
 //  public:
 //   // Element is the type of the compacted transitions.
 //   using Element = ...
@@ -82,10 +135,10 @@ struct CompactFstOptions : public CacheOptions {
 //   bool Write(std::ostream &strm) const;
 //
 //   // Reads a compactor from a file.
-//   static Compactor *Read(std::istream &strm);
+//   static ArcCompactor *Read(std::istream &strm);
 //
 //   // Default constructor (optional, see comment below).
-//   Compactor();
+//   ArcCompactor();
 // };
 //
 // The default constructor is only required for FST_REGISTER to work (i.e.,
@@ -404,11 +457,275 @@ bool DefaultCompactStore<Element, Unsigned>::Write(
 
 template <class Element, class Unsigned>
 const string &DefaultCompactStore<Element, Unsigned>::Type() {
-  static const string type = "compact";
-  return type;
+  static const string *const type = new string("compact");
+  return *type;
 }
 
-template <class Arc, class Element, class Unsigned, class CompactStore,
+template <class C, class U, class S> class DefaultCompactState;
+
+// Wraps an arc compactor and a compact store as a new Fst compactor.
+template <class C, class U,
+          class S = DefaultCompactStore<typename C::Element, U>>
+class DefaultCompactor {
+ public:
+  using ArcCompactor = C;
+  using Unsigned = U;
+  using CompactStore = S;
+  using Element = typename C::Element;
+  using Arc = typename C::Arc;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
+  using State = DefaultCompactState<C, U, S>;
+  friend State;
+
+  DefaultCompactor()
+      : arc_compactor_(nullptr), compact_store_(nullptr) {}
+
+  // Constructs from Fst.
+  DefaultCompactor(const Fst<Arc> &fst,
+                   std::shared_ptr<ArcCompactor> arc_compactor)
+      : arc_compactor_(std::move(arc_compactor)),
+        compact_store_(std::make_shared<S>(fst, *arc_compactor_)) {}
+
+  DefaultCompactor(const Fst<Arc> &fst,
+                   std::shared_ptr<DefaultCompactor<C, U, S>> compactor)
+      : arc_compactor_(compactor->arc_compactor_),
+        compact_store_(compactor->compact_store_ == nullptr ?
+                       std::make_shared<S>(fst, *arc_compactor_) :
+                       compactor->compact_store_) {}
+
+  // Constructs from CompactStore.
+  DefaultCompactor(std::shared_ptr<ArcCompactor> arc_compactor,
+                   std::shared_ptr<CompactStore> compact_store)
+      : arc_compactor_(std::move(arc_compactor)),
+        compact_store_(std::move(compact_store)) {}
+
+  // Constructs from set of compact elements (when arc_compactor.Size() != -1).
+  template <class Iterator>
+  DefaultCompactor(const Iterator &b, const Iterator &e,
+                   std::shared_ptr<C> arc_compactor)
+      : arc_compactor_(std::move(arc_compactor)),
+        compact_store_(std::make_shared<S>(b, e, *arc_compactor_)) {}
+
+  // Copy constructor.
+  DefaultCompactor(const DefaultCompactor<C, U, S> &compactor)
+      : arc_compactor_(std::make_shared<C>(*compactor.GetArcCompactor())),
+        compact_store_(compactor.SharedCompactStore()) {}
+
+  template <class OtherC>
+  explicit DefaultCompactor(const DefaultCompactor<OtherC, U, S> &compactor)
+      : arc_compactor_(std::make_shared<C>(*compactor.GetArcCompactor())),
+        compact_store_(compactor.SharedCompactStore()) {}
+
+  StateId Start() const { return compact_store_->Start(); }
+  StateId NumStates() const { return compact_store_->NumStates(); }
+  size_t NumArcs() const { return compact_store_->NumArcs(); }
+
+  void SetState(StateId s, State *state) const {
+    if (state->GetStateId() != s) state->Set(this, s);
+  }
+
+  static DefaultCompactor<C, U, S> *Read(std::istream &strm,
+                                         const FstReadOptions &opts,
+                                         const FstHeader &hdr) {
+    std::shared_ptr<C> arc_compactor(C::Read(strm));
+    if (arc_compactor == nullptr) return nullptr;
+    std::shared_ptr<S> compact_store(S::Read(strm, opts, hdr, *arc_compactor));
+    if (compact_store == nullptr) return nullptr;
+    return new DefaultCompactor<C, U, S>(arc_compactor, compact_store);
+  }
+
+  bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
+    return arc_compactor_->Write(strm) && compact_store_->Write(strm, opts);
+  }
+
+  uint64 Properties() const { return arc_compactor_->Properties(); }
+
+  bool IsCompatible(const Fst<Arc> &fst) const {
+    return arc_compactor_->Compatible(fst);
+  }
+
+  bool Error() const { return compact_store_->Error(); }
+
+  bool HasFixedOutdegree() const { return arc_compactor_->Size() != -1; }
+
+  static const string &Type() {
+    static const string *const type = [] {
+      string type = "compact";
+      if (sizeof(U) != sizeof(uint32)) type += std::to_string(8 * sizeof(U));
+      type += "_";
+      type += C::Type();
+      if (CompactStore::Type() != "compact") {
+        type += "_";
+        type += CompactStore::Type();
+      }
+      return new string(type);
+    }();
+    return *type;
+  }
+
+  const ArcCompactor *GetArcCompactor() const { return arc_compactor_.get(); }
+  CompactStore *GetCompactStore() const { return compact_store_.get(); }
+
+  std::shared_ptr<ArcCompactor> SharedArcCompactor() const {
+    return arc_compactor_;
+  }
+
+  std::shared_ptr<CompactStore> SharedCompactStore() const {
+    return compact_store_;
+  }
+
+  // TODO(allauzen): remove dependencies on this method and make private.
+  Arc ComputeArc(StateId s, Unsigned i, uint32 f) const {
+    return arc_compactor_->Expand(s, compact_store_->Compacts(i), f);
+  }
+
+ private:
+  std::pair<Unsigned, Unsigned> CompactsRange(StateId s) const {
+    std::pair<size_t, size_t> range;
+    if (HasFixedOutdegree()) {
+      range.first = s * arc_compactor_->Size();
+      range.second = arc_compactor_->Size();
+    } else {
+      range.first = compact_store_->States(s);
+      range.second = compact_store_->States(s + 1) - range.first;
+    }
+    return range;
+  }
+
+ private:
+  std::shared_ptr<ArcCompactor> arc_compactor_;
+  std::shared_ptr<CompactStore> compact_store_;
+};
+
+// Default implementation of state attributes accessor class for
+// DefaultCompactor. Use of efficient specialization strongly encouraged.
+template <class C, class U, class S>
+class DefaultCompactState {
+ public:
+  using Arc = typename C::Arc;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
+
+  DefaultCompactState() = default;
+
+  DefaultCompactState(const DefaultCompactor<C, U, S> *compactor, StateId s)
+      : compactor_(compactor),
+        s_(s),
+        range_(compactor->CompactsRange(s)),
+        has_final_(
+            range_.second != 0 &&
+            compactor->ComputeArc(s, range_.first,
+                                 kArcILabelValue).ilabel == kNoLabel) {
+    if (has_final_) {
+      ++range_.first;
+      --range_.second;
+    }
+  }
+
+  void Set(const DefaultCompactor<C, U, S> *compactor, StateId s) {
+    compactor_ = compactor;
+    s_ = s;
+    range_ = compactor->CompactsRange(s);
+    if (range_.second != 0 &&
+        compactor->ComputeArc(s, range_.first, kArcILabelValue).ilabel
+        == kNoLabel) {
+      has_final_ = true;
+      ++range_.first;
+      --range_.second;
+    } else {
+      has_final_ = false;
+    }
+  }
+
+  StateId GetStateId() const { return s_; }
+
+  Weight Final() const {
+    if (!has_final_) return Weight::Zero();
+    return compactor_->ComputeArc(s_, range_.first - 1, kArcWeightValue).weight;
+  }
+
+  size_t NumArcs() const { return range_.second; }
+
+  Arc GetArc(size_t i, uint32 f) const {
+    return compactor_->ComputeArc(s_, range_.first + i, f);
+  }
+
+ private:
+  const DefaultCompactor<C, U, S> *compactor_ = nullptr;  // borrowed ref.
+  StateId s_ = kNoStateId;
+  std::pair<U, U> range_ = {0, 0};
+  bool has_final_ = false;
+};
+
+// Specialization for DefaultCompactStore.
+template <class C, class U>
+class DefaultCompactState<C, U, DefaultCompactStore<typename C::Element, U>> {
+ public:
+  using Arc = typename C::Arc;
+  using StateId = typename Arc::StateId;
+  using Weight = typename Arc::Weight;
+  using CompactStore = DefaultCompactStore<typename C::Element, U>;
+
+  DefaultCompactState() = default;
+
+  DefaultCompactState(
+      const DefaultCompactor<C, U, CompactStore> *compactor, StateId s)
+      : arc_compactor_(compactor->GetArcCompactor()), s_(s) {
+    Init(compactor);
+  }
+
+  void Set(const DefaultCompactor<C, U, CompactStore> *compactor, StateId s) {
+    arc_compactor_ = compactor->GetArcCompactor();
+    s_ = s;
+    has_final_ = false;
+    Init(compactor);
+  }
+
+  StateId GetStateId() const { return s_; }
+
+  Weight Final() const {
+    if (!has_final_) return Weight::Zero();
+    return arc_compactor_->Expand(s_, *(compacts_ - 1), kArcWeightValue).weight;
+  }
+
+  size_t NumArcs() const { return num_arcs_; }
+
+  Arc GetArc(size_t i, uint32 f) const {
+    return arc_compactor_->Expand(s_, compacts_[i], f);
+  }
+
+ private:
+  void Init(const DefaultCompactor<C, U, CompactStore> *compactor) {
+    const auto *store = compactor->GetCompactStore();
+    U offset;
+    if (!compactor->HasFixedOutdegree()) {  // Variable out-degree compactor.
+      offset = store->States(s_);
+      num_arcs_ = store->States(s_ + 1) - offset;
+    } else {  // Fixed out-degree compactor.
+      offset = s_ * arc_compactor_->Size();
+      num_arcs_ = arc_compactor_->Size();
+    }
+    if (num_arcs_ > 0) {
+      compacts_ = &(store->Compacts(offset));
+      if (arc_compactor_->Expand(s_, *compacts_, kArcILabelValue).ilabel
+          == kNoStateId) {
+        ++compacts_;
+        --num_arcs_;
+        has_final_ = true;
+      }
+    }
+  }
+
+ private:
+  const C *arc_compactor_ = nullptr;               // Borrowed reference.
+  const typename C::Element *compacts_ = nullptr;  // Borrowed reference.
+  StateId s_ = kNoStateId;
+  U num_arcs_ = 0;
+  bool has_final_ = false;
+};
+
+template <class Arc, class ArcCompactor, class Unsigned, class CompactStore,
           class CacheStore>
 class CompactFst;
 
@@ -419,16 +736,13 @@ namespace internal {
 
 // Implementation class for CompactFst, which contains parametrizeable
 // Fst data storage (DefaultCompactStore by default) and Fst cache.
-template <class Arc, class Compactor, class Unsigned,
-          class CompactStore =
-              DefaultCompactStore<typename Compactor::Element, Unsigned>,
-          class CacheStore = DefaultCacheStore<Arc>>
+template <class Arc, class C, class CacheStore = DefaultCacheStore<Arc>>
 class CompactFstImpl
     : public CacheBaseImpl<typename CacheStore::State, CacheStore> {
  public:
-  using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using DataStorage = CompactStore;
+  using StateId = typename Arc::StateId;
+  using Compactor = C;
 
   using FstImpl<Arc>::SetType;
   using FstImpl<Arc>::SetProperties;
@@ -448,46 +762,46 @@ class CompactFstImpl
 
   CompactFstImpl()
       : ImplBase(CompactFstOptions()),
-        compactor_(),
-        data_() {
-    string type = "compact";
-    if (sizeof(Unsigned) != sizeof(uint32)) {
-      string size;
-      Int64ToStr(8 * sizeof(Unsigned), &size);
-      type += size;
-    }
-    type += "_";
-    type += Compactor::Type();
-    if (CompactStore::Type() != "compact") {
-      type += "_";
-      type += CompactStore::Type();
-    }
-    SetType(type);
+        compactor_() {
+    SetType(Compactor::Type());
     SetProperties(kNullProperties | kStaticProperties);
   }
 
   CompactFstImpl(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
-                 const CompactFstOptions &opts,
-                 std::shared_ptr<CompactStore> data)
-      : ImplBase(opts), compactor_(std::move(compactor)) {
-    Init(fst, data);
+                 const CompactFstOptions &opts)
+      : ImplBase(opts),
+        compactor_(std::make_shared<Compactor>(fst, compactor)) {
+    SetType(Compactor::Type());
+    SetInputSymbols(fst.InputSymbols());
+    SetOutputSymbols(fst.OutputSymbols());
+    if (compactor_->Error()) SetProperties(kError, kError);
+    uint64 copy_properties = fst.Properties(kMutable, false) ?
+        fst.Properties(kCopyProperties, true):
+        CheckProperties(fst,
+                        kCopyProperties & ~kWeightedCycles & ~kUnweightedCycles,
+                        kCopyProperties);
+    if ((copy_properties & kError) || !compactor_->IsCompatible(fst)) {
+      FSTERROR() << "CompactFstImpl: Input Fst incompatible with compactor";
+      SetProperties(kError, kError);
+      return;
+    }
+    SetProperties(copy_properties | kStaticProperties);
   }
 
-  template <class Iterator>
-  CompactFstImpl(const Iterator &b, const Iterator &e,
-                 std::shared_ptr<Compactor> compactor,
+  CompactFstImpl(std::shared_ptr<Compactor> compactor,
                  const CompactFstOptions &opts)
-      : ImplBase(opts), compactor_(std::move(compactor)) {
-    Init(b, e);
+      : ImplBase(opts),
+        compactor_(compactor) {
+    SetType(Compactor::Type());
+    SetProperties(kStaticProperties | compactor_->Properties());
+    if (compactor_->Error()) SetProperties(kError, kError);
   }
 
-  CompactFstImpl(const CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                                      CacheStore> &impl)
+  CompactFstImpl(const CompactFstImpl<Arc, Compactor, CacheStore> &impl)
       : ImplBase(impl),
-        compactor_(impl.compactor_ == nullptr
-                       ? nullptr
-                       : std::make_shared<Compactor>(*impl.compactor_)),
-        data_(impl.data_) {
+        compactor_(impl.compactor_ == nullptr ?
+                   std::make_shared<Compactor>() :
+                   std::make_shared<Compactor>(*impl.compactor_)) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
@@ -496,14 +810,11 @@ class CompactFstImpl
 
   // Allows to change the cache store from OtherI to I.
   template <class OtherCacheStore>
-  explicit CompactFstImpl(
-      const CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                           OtherCacheStore> &impl)
+  CompactFstImpl(const CompactFstImpl<Arc, Compactor, OtherCacheStore> &impl)
       : ImplBase(CacheOptions(impl.GetCacheGc(), impl.GetCacheLimit())),
-        compactor_(impl.compactor_ == nullptr
-                       ? nullptr
-                       : std::make_shared<Compactor>(*impl.compactor_)),
-        data_(impl.data_) {
+        compactor_(impl.compactor_ == nullptr ?
+                   std::make_shared<Compactor>() :
+                   std::make_shared<Compactor>(*impl.compactor_)) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
@@ -511,42 +822,25 @@ class CompactFstImpl
   }
 
   StateId Start() {
-    if (!HasStart()) SetStart(data_->Start());
+    if (!HasStart()) SetStart(compactor_->Start());
     return ImplBase::Start();
   }
 
   Weight Final(StateId s) {
     if (HasFinal(s)) return ImplBase::Final(s);
-    Arc arc(kNoLabel, kNoLabel, Weight::Zero(), kNoStateId);
-    if ((compactor_->Size() != -1) ||
-        (data_->States(s) != data_->States(s + 1))) {
-      arc = ComputeArc(s, compactor_->Size() == -1 ? data_->States(s) :
-                       s * compactor_->Size());
-    }
-    return arc.ilabel == kNoLabel ? arc.weight : Weight::Zero();
+    compactor_->SetState(s, &state_);
+    return state_.Final();
   }
 
   StateId NumStates() const {
     if (Properties(kError)) return 0;
-    return data_->NumStates();
+    return compactor_->NumStates();
   }
 
   size_t NumArcs(StateId s) {
     if (HasArcs(s)) return ImplBase::NumArcs(s);
-    Unsigned i;
-    Unsigned num_arcs;
-    if (compactor_->Size() == -1) {
-      i = data_->States(s);
-      num_arcs = data_->States(s + 1) - i;
-    } else {
-      i = s * compactor_->Size();
-      num_arcs = compactor_->Size();
-    }
-    if (num_arcs > 0) {
-      const auto &arc = ComputeArc(s, i, kArcILabelValue);
-      if (arc.ilabel == kNoStateId) --num_arcs;
-    }
-    return num_arcs;
+    compactor_->SetState(s, &state_);
+    return state_.NumArcs();
   }
 
   size_t NumInputEpsilons(StateId s) {
@@ -562,31 +856,24 @@ class CompactFstImpl
   }
 
   size_t CountEpsilons(StateId s, bool output_epsilons) {
-    size_t begin =
-        compactor_->Size() == -1 ? data_->States(s) : s * compactor_->Size();
-    size_t end = compactor_->Size() == -1 ? data_->States(s + 1)
-                                          : (s + 1) * compactor_->Size();
+    compactor_->SetState(s, &state_);
+    const uint32 f = output_epsilons ? kArcOLabelValue : kArcILabelValue;
     size_t num_eps = 0;
-    for (size_t i = begin; i < end; ++i) {
-      const auto &arc =
-          ComputeArc(s, i, output_epsilons ? kArcOLabelValue : kArcILabelValue);
+    for (size_t i = 0; i < state_.NumArcs(); ++i) {
+      const auto& arc = state_.GetArc(i, f);
       const auto label = output_epsilons ? arc.olabel : arc.ilabel;
-      if (label == kNoLabel) {
-        continue;
-      } else if (label > 0) {
+      if (label == 0)
+        ++num_eps;
+      else if (label > 0)
         break;
-      }
-      ++num_eps;
     }
     return num_eps;
   }
 
-  static CompactFstImpl<Arc, Compactor, Unsigned, CompactStore, CacheStore>
-      *Read(std::istream &strm, const FstReadOptions &opts) {
-    std::unique_ptr<
-        CompactFstImpl<Arc, Compactor, Unsigned, CompactStore, CacheStore>>
-        impl(new CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                                CacheStore>());
+  static CompactFstImpl<Arc, Compactor, CacheStore> *Read(
+      std::istream &strm, const FstReadOptions &opts) {
+    std::unique_ptr<CompactFstImpl<Arc, Compactor, CacheStore>> impl(
+      new CompactFstImpl<Arc, Compactor, CacheStore>());
     FstHeader hdr;
     if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) {
       return nullptr;
@@ -595,30 +882,29 @@ class CompactFstImpl
     if (hdr.Version() == kAlignedFileVersion) {
       hdr.SetFlags(hdr.GetFlags() | FstHeader::IS_ALIGNED);
     }
-    impl->compactor_ = std::shared_ptr<Compactor>(Compactor::Read(strm));
-    if (!impl->compactor_) return nullptr;
-    impl->data_ = std::shared_ptr<CompactStore>(
-        CompactStore::Read(strm, opts, hdr, *impl->compactor_));
-    if (!impl->data_) return nullptr;
+    impl->compactor_ = std::shared_ptr<Compactor>(
+        Compactor::Read(strm, opts, hdr));
+    if (!impl->compactor_) {
+      return nullptr;
+    }
     return impl.release();
   }
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
     FstHeader hdr;
-    hdr.SetStart(data_->Start());
-    hdr.SetNumStates(data_->NumStates());
-    hdr.SetNumArcs(data_->NumArcs());
+    hdr.SetStart(compactor_->Start());
+    hdr.SetNumStates(compactor_->NumStates());
+    hdr.SetNumArcs(compactor_->NumArcs());
     // Ensures compatibility.
     const auto file_version = opts.align ? kAlignedFileVersion : kFileVersion;
     WriteHeader(strm, opts, file_version, &hdr);
-    compactor_->Write(strm);
-    return data_->Write(strm, opts);
+    return compactor_->Write(strm, opts);
   }
 
   // Provides information needed for generic state iterator.
   void InitStateIterator(StateIteratorData<Arc> *data) const {
     data->base = nullptr;
-    data->nstates = data_->NumStates();
+    data->nstates = compactor_->NumStates();
   }
 
   void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) {
@@ -626,41 +912,22 @@ class CompactFstImpl
     ImplBase::InitArcIterator(s, data);
   }
 
-  Arc ComputeArc(StateId s, Unsigned i, uint32 f = kArcValueFlags) const {
-    return compactor_->Expand(s, data_->Compacts(i), f);
-  }
-
   void Expand(StateId s) {
-    size_t begin =
-        compactor_->Size() == -1 ? data_->States(s) : s * compactor_->Size();
-    size_t end = compactor_->Size() == -1 ? data_->States(s + 1)
-                                          : (s + 1) * compactor_->Size();
-    for (auto i = begin; i < end; ++i) {
-      const auto &arc = ComputeArc(s, i);
-      if (arc.ilabel == kNoLabel) {
-        SetFinal(s, arc.weight);
-      } else {
-        PushArc(s, arc);
-      }
-    }
-    if (!HasFinal(s)) SetFinal(s, Weight::Zero());
+    compactor_->SetState(s, &state_);
+    for (size_t i = 0; i < state_.NumArcs(); ++i)
+      PushArc(s, state_.GetArc(i, kArcValueFlags));
     SetArcs(s);
-  }
-
-  template <class Iterator>
-  void SetCompactElements(const Iterator &begin, const Iterator &end) {
-    SetProperties(kStaticProperties | compactor_->Properties());
-    data_ = std::make_shared<CompactStore>(begin, end, *compactor_);
-    if (data_->Error()) SetProperties(kError, kError);
+    if (!HasFinal(s)) SetFinal(s, state_.Final());
   }
 
   const Compactor *GetCompactor() const { return compactor_.get(); }
-
   std::shared_ptr<Compactor> SharedCompactor() const { return compactor_; }
-
-  const CompactStore *Data() const { return data_.get(); }
-
-  std::shared_ptr<CompactStore> SharedData() const { return data_; }
+  void SetCompactor(std::shared_ptr<Compactor> compactor) {
+    // TODO(allauzen): is this correct? is this needed?
+    // TODO(allauzen): consider removing and forcing this through direct calls
+    // to compactor.
+    compactor_ = compactor;
+  }
 
   // Properties always true of this FST class.
   static constexpr uint64 kStaticProperties = kExpanded;
@@ -668,11 +935,8 @@ class CompactFstImpl
  protected:
   template <class OtherArc, class OtherCompactor, class OtherCacheStore>
   explicit CompactFstImpl(
-      const CompactFstImpl<OtherArc, OtherCompactor, Unsigned, CompactStore,
-                           OtherCacheStore> &impl)
-      : ImplBase(CacheOptions(impl.GetCacheGc(), impl.GetCacheLimit())),
-        compactor_(std::make_shared<Compactor>(*impl.GetCompactor())),
-        data_(impl.SharedData()) {
+    const CompactFstImpl<OtherArc, OtherCompactor, OtherCacheStore> &impl)
+    : compactor_(std::make_shared<Compactor>(*impl.GetCompactor())) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
@@ -681,55 +945,9 @@ class CompactFstImpl
 
  private:
   // Allows access during write.
-  friend class CompactFst<Arc, Compactor, Unsigned, CompactStore, CacheStore>;
-
-  void Init(const Fst<Arc> &fst, std::shared_ptr<CompactStore> data) {
-    string type = "compact";
-    if (sizeof(Unsigned) != sizeof(uint32)) {
-      string size;
-      Int64ToStr(8 * sizeof(Unsigned), &size);
-      type += size;
-    }
-    type += "_";
-    type += compactor_->Type();
-    if (CompactStore::Type() != "compact") {
-      type += "_";
-      type += CompactStore::Type();
-    }
-    SetType(type);
-    SetInputSymbols(fst.InputSymbols());
-    SetOutputSymbols(fst.OutputSymbols());
-    data_ = (data) ? data : std::make_shared<CompactStore>(fst, *compactor_);
-    if (data_->Error()) SetProperties(kError, kError);
-    const auto copy_properties =
-        fst.Properties(kMutable, false)
-            ? fst.Properties(kCopyProperties, true)
-            : CheckProperties(
-                  fst, kCopyProperties & ~kWeightedCycles & ~kUnweightedCycles,
-                  kCopyProperties);
-    if ((copy_properties & kError) || !compactor_->Compatible(fst)) {
-      FSTERROR() << "CompactFstImpl: Input FST incompatible with compactor";
-      SetProperties(kError, kError);
-      return;
-    }
-    SetProperties(copy_properties | kStaticProperties);
-  }
-
-  template <class Iterator>
-  void Init(const Iterator &begin, const Iterator &end) {
-    string type = "compact";
-    if (sizeof(Unsigned) != sizeof(uint32)) {
-      string size;
-      Int64ToStr(8 * sizeof(Unsigned), &size);
-      type += size;
-    }
-    type += "_";
-    type += compactor_->Type();
-    SetType(type);
-    SetProperties(kStaticProperties | compactor_->Properties());
-    data_ = std::make_shared<CompactStore>(begin, end, *compactor_);
-    if (data_->Error()) SetProperties(kError, kError);
-  }
+  template <class AnyArc, class ArcCompactor, class Unsigned,
+            class CompactStore, class AnyCacheStore>
+  friend class ::fst::CompactFst;  // allow access during write.
 
   // Current unaligned file format version.
   static constexpr int kFileVersion = 2;
@@ -739,28 +957,20 @@ class CompactFstImpl
   static constexpr int kMinFileVersion = 1;
 
   std::shared_ptr<Compactor> compactor_;
-  std::shared_ptr<CompactStore> data_;
+  typename Compactor::State state_;
 };
 
-template <class Arc, class Compactor, class Unsigned, class CompactStore,
-          class CacheStore>
-constexpr uint64 CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                                CacheStore>::kStaticProperties;
+template <class Arc, class Compactor, class CacheStore>
+constexpr uint64 CompactFstImpl<Arc, Compactor, CacheStore>::kStaticProperties;
 
-template <class Arc, class Compactor, class Unsigned, class CompactStore,
-          class CacheStore>
-constexpr int CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                             CacheStore>::kFileVersion;
+template <class Arc, class Compactor, class CacheStore>
+constexpr int CompactFstImpl<Arc, Compactor, CacheStore>::kFileVersion;
 
-template <class Arc, class Compactor, class Unsigned, class CompactStore,
-          class CacheStore>
-constexpr int CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                             CacheStore>::kAlignedFileVersion;
+template <class Arc, class Compactor, class CacheStore>
+constexpr int CompactFstImpl<Arc, Compactor, CacheStore>::kAlignedFileVersion;
 
-template <class Arc, class Compactor, class Unsigned, class CompactStore,
-          class CacheStore>
-constexpr int CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
-                             CacheStore>::kMinFileVersion;
+template <class Arc, class Compactor, class CacheStore>
+constexpr int CompactFstImpl<Arc, Compactor, CacheStore>::kMinFileVersion;
 
 }  // namespace internal
 
@@ -768,42 +978,53 @@ constexpr int CompactFstImpl<Arc, Compactor, Unsigned, CompactStore,
 // counting, delegating most methods to ImplToExpandedFst. The Unsigned type
 // is used to represent indices into the compact arc array. (Template
 // argument defaults are declared in fst-decl.h.)
-template <class A, class Compactor, class Unsigned, class CompactStore,
+template <class A, class ArcCompactor, class Unsigned, class CompactStore,
           class CacheStore>
-class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
-                       A, Compactor, Unsigned, CompactStore, CacheStore>> {
+class CompactFst
+    : public ImplToExpandedFst<internal::CompactFstImpl<
+          A,
+          DefaultCompactor<ArcCompactor, Unsigned, CompactStore>,
+          CacheStore>> {
  public:
   template <class F, class G>
   void friend Cast(const F &, G *);
 
   using Arc = A;
-  using StateId = typename Arc::StateId;
-
-  using Impl = internal::CompactFstImpl<A, Compactor, Unsigned, CompactStore,
-                                        CacheStore>;
+  using StateId = typename A::StateId;
+  using Compactor = DefaultCompactor<ArcCompactor, Unsigned, CompactStore>;
+  using Impl = internal::CompactFstImpl<A, Compactor, CacheStore>;
+  using Store = CacheStore;  // for CacheArcIterator
 
   friend class StateIterator<
-      CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>>;
+      CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>;
   friend class ArcIterator<
-      CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>>;
+      CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>;
 
   CompactFst() : ImplToExpandedFst<Impl>(std::make_shared<Impl>()) {}
 
   // If data is not nullptr, it is assumed to be already initialized.
   explicit CompactFst(
-      const Fst<Arc> &fst, const Compactor &compactor = Compactor(),
+      const Fst<A> &fst,
+      const ArcCompactor &compactor = ArcCompactor(),
       const CompactFstOptions &opts = CompactFstOptions(),
       std::shared_ptr<CompactStore> data = std::shared_ptr<CompactStore>())
-      : ImplToExpandedFst<Impl>(std::make_shared<Impl>(
-            fst, std::make_shared<Compactor>(compactor), opts, data)) {}
+      : ImplToExpandedFst<Impl>(
+            std::make_shared<Impl>(
+                fst,
+                std::make_shared<Compactor>(
+                    std::make_shared<ArcCompactor>(compactor), data),
+                opts)) {}
 
   // If data is not nullptr, it is assumed to be already initialized.
   CompactFst(
-      const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
+      const Fst<Arc> &fst,
+      std::shared_ptr<ArcCompactor> compactor,
       const CompactFstOptions &opts = CompactFstOptions(),
       std::shared_ptr<CompactStore> data = std::shared_ptr<CompactStore>())
       : ImplToExpandedFst<Impl>(
-            std::make_shared<Impl>(fst, compactor, opts, data)) {}
+            std::make_shared<Impl>(fst,
+                                   std::make_shared<Compactor>(compactor, data),
+                                   opts)) {}
 
   // The following 2 constructors take as input two iterators delimiting a set
   // of (already) compacted transitions, starting with the transitions out of
@@ -825,46 +1046,51 @@ class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
   // when memory usage is severely constrained.
   template <class Iterator>
   explicit CompactFst(const Iterator &begin, const Iterator &end,
-                      const Compactor &compactor = Compactor(),
+                      const ArcCompactor &compactor = ArcCompactor(),
                       const CompactFstOptions &opts = CompactFstOptions())
-      : ImplToExpandedFst<Impl>(std::make_shared<Impl>(
-            begin, end, std::make_shared<Compactor>(compactor), opts)) {}
+      : ImplToExpandedFst<Impl>(
+            std::make_shared<Impl>(
+                std::make_shared<Compactor>(
+                    begin, end, std::make_shared<ArcCompactor>(compactor)),
+                opts)) {}
 
   template <class Iterator>
   CompactFst(const Iterator &begin, const Iterator &end,
-             std::shared_ptr<Compactor> compactor,
+             std::shared_ptr<ArcCompactor> compactor,
              const CompactFstOptions &opts = CompactFstOptions())
       : ImplToExpandedFst<Impl>(
-            std::make_shared<Impl>(begin, end, compactor, opts)) {}
+            std::make_shared<Impl>(
+                std::make_shared<Compactor>(begin, end, compactor), opts)) {}
 
   // See Fst<>::Copy() for doc.
   CompactFst(
-      const CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore> &fst,
+      const CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>
+      &fst,
       bool safe = false)
       : ImplToExpandedFst<Impl>(fst, safe) {}
 
   // Get a copy of this CompactFst. See Fst<>::Copy() for further doc.
-  CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore> *Copy(
+  CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Copy(
       bool safe = false) const override {
-    return new CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>(
+    return new CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>(
         *this, safe);
   }
 
   // Read a CompactFst from an input stream; return nullptr on error
-  static CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore> *Read(
+  static CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Read(
       std::istream &strm, const FstReadOptions &opts) {
     auto *impl = Impl::Read(strm, opts);
-    return impl ? new CompactFst<A, Compactor, Unsigned, CompactStore,
+    return impl ? new CompactFst<A, ArcCompactor, Unsigned, CompactStore,
                                  CacheStore>(std::shared_ptr<Impl>(impl))
                 : nullptr;
   }
 
   // Read a CompactFst from a file; return nullptr on error
   // Empty filename reads from standard input
-  static CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore> *Read(
+  static CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore> *Read(
       const string &filename) {
     auto *impl = ImplToExpandedFst<Impl>::Read(filename);
-    return impl ? new CompactFst<A, Compactor, Unsigned, CompactStore,
+    return impl ? new CompactFst<A, ArcCompactor, Unsigned, CompactStore,
                                  CacheStore>(std::shared_ptr<Impl>(impl))
                 : nullptr;
   }
@@ -878,7 +1104,7 @@ class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
   }
 
   template <class FST>
-  static bool WriteFst(const FST &fst, const Compactor &compactor,
+  static bool WriteFst(const FST &fst, const ArcCompactor &compactor,
                        std::ostream &strm, const FstWriteOptions &opts);
 
   void InitStateIterator(StateIteratorData<Arc> *data) const override {
@@ -891,13 +1117,14 @@ class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
 
   MatcherBase<Arc> *InitMatcher(MatchType match_type) const override {
     return new SortedMatcher<
-        CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>>(
+        CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>>(
         *this, match_type);
   }
 
   template <class Iterator>
-  void SetCompactElements(const Iterator &begin, const Iterator &end) {
-    GetMutableImpl()->SetCompactElements(begin, end);
+  void SetCompactElements(const Iterator &b, const Iterator &e) {
+    GetMutableImpl()->SetCompactor(std::make_shared<Compactor>(
+        b, e, std::make_shared<ArcCompactor>()));
   }
 
  private:
@@ -909,7 +1136,7 @@ class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
 
   // Use overloading to extract the type of the argument.
   static Impl *GetImplIfCompactFst(
-      const CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>
+      const CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>
           &compact_fst) {
     return compact_fst.GetImpl();
   }
@@ -925,24 +1152,24 @@ class CompactFst : public ImplToExpandedFst<internal::CompactFstImpl<
 
 // Writes FST in Compact format, with a possible pass over the machine before
 // writing to compute the number of states and arcs.
-template <class A, class Compactor, class Unsigned, class CompactStore,
+template <class A, class ArcCompactor, class Unsigned, class CompactStore,
           class CacheStore>
 template <class FST>
-bool CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>::WriteFst(
-    const FST &fst, const Compactor &compactor, std::ostream &strm,
+bool CompactFst<A, ArcCompactor, Unsigned, CompactStore, CacheStore>::WriteFst(
+    const FST &fst, const ArcCompactor &compactor, std::ostream &strm,
     const FstWriteOptions &opts) {
   using Arc = A;
   using Weight = typename A::Weight;
-  using Element = typename Compactor::Element;
+  using Element = typename ArcCompactor::Element;
   const auto file_version =
       opts.align ? Impl::kAlignedFileVersion : Impl::kFileVersion;
   size_t num_arcs = -1;
   size_t num_states = -1;
   auto first_pass_compactor = compactor;
   if (auto *impl = GetImplIfCompactFst(fst)) {
-    num_arcs = impl->Data()->NumArcs();
-    num_states = impl->Data()->NumStates();
-    first_pass_compactor = *impl->GetCompactor();
+    num_arcs = impl->GetCompactor()->GetCompactStore()->NumArcs();
+    num_states = impl->GetCompactor()->GetCompactStore()->NumStates();
+    first_pass_compactor = *impl->GetCompactor()->GetArcCompactor();
   } else {
     // A first pass is needed to compute the state of the compactor, which
     // is saved ahead of the rest of the data structures. This unfortunately
@@ -969,12 +1196,10 @@ bool CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>::WriteFst(
   hdr.SetNumArcs(num_arcs);
   string type = "compact";
   if (sizeof(Unsigned) != sizeof(uint32)) {
-    string size;
-    Int64ToStr(8 * sizeof(Unsigned), &size);
-    type += size;
+    type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
   type += "_";
-  type += Compactor::Type();
+  type += ArcCompactor::Type();
   if (CompactStore::Type() != "compact") {
     type += "_";
     type += CompactStore::Type();
@@ -1031,15 +1256,16 @@ bool CompactFst<A, Compactor, Unsigned, CompactStore, CacheStore>::WriteFst(
 
 // Specialization for CompactFst; see generic version in fst.h for sample
 // usage (but use the CompactFst type!). This version should inline.
-template <class Arc, class Compactor, class Unsigned, class CompactStore,
+template <class Arc, class ArcCompactor, class Unsigned, class CompactStore,
           class CacheStore>
 class StateIterator<
-    CompactFst<Arc, Compactor, Unsigned, CompactStore, CacheStore>> {
+    CompactFst<Arc, ArcCompactor, Unsigned, CompactStore, CacheStore>> {
  public:
   using StateId = typename Arc::StateId;
 
   explicit StateIterator(
-      const CompactFst<Arc, Compactor, Unsigned, CompactStore, CacheStore> &fst)
+      const CompactFst<Arc, ArcCompactor, Unsigned, CompactStore,
+                       CacheStore> &fst)
       : nstates_(fst.GetImpl()->NumStates()), s_(0) {}
 
   bool Done() const { return s_ >= nstates_; }
@@ -1055,48 +1281,29 @@ class StateIterator<
   StateId s_;
 };
 
-// Specialization for CompactFst with DefaultCompactStore. Never caches,
+// Specialization for CompactFst. Never caches,
 // always iterates over the underlying compact elements.
-template <class Arc, class Compactor, class Unsigned, class CacheStore>
+template <class Arc, class ArcCompactor, class Unsigned,
+          class CompactStore, class CacheStore>
 class ArcIterator<CompactFst<
-    Arc, Compactor, Unsigned,
-    DefaultCompactStore<typename Compactor::Element, Unsigned>, CacheStore>> {
+    Arc, ArcCompactor, Unsigned, CompactStore, CacheStore>> {
  public:
   using StateId = typename Arc::StateId;
-  using Element = typename Compactor::Element;
-
-  ArcIterator(
-      const CompactFst<Arc, Compactor, Unsigned,
-                       DefaultCompactStore<Element, Unsigned>, CacheStore> &fst,
-      StateId s)
-      : compactor_(fst.GetImpl()->GetCompactor()),
-        state_(s),
-        compacts_(nullptr),
+  using Element = typename ArcCompactor::Element;
+  using Compactor = DefaultCompactor<ArcCompactor, Unsigned, CompactStore>;
+  using State = typename Compactor::State;
+
+  ArcIterator(const CompactFst<Arc, ArcCompactor, Unsigned, CompactStore,
+                               CacheStore> &fst,
+              StateId s)
+      : state_(fst.GetImpl()->GetCompactor(), s),
         pos_(0),
-        flags_(kArcValueFlags) {
-    const auto *data = fst.GetImpl()->Data();
-    size_t offset;
-    if (compactor_->Size() == -1) {  // Variable out-degree compactor.
-      offset = data->States(s);
-      num_arcs_ = data->States(s + 1) - offset;
-    } else {  // Fixed out-degree compactor.
-      offset = s * compactor_->Size();
-      num_arcs_ = compactor_->Size();
-    }
-    if (num_arcs_ > 0) {
-      compacts_ = &(data->Compacts(offset));
-      arc_ = compactor_->Expand(s, *compacts_, kArcILabelValue);
-      if (arc_.ilabel == kNoStateId) {
-        ++compacts_;
-        --num_arcs_;
-      }
-    }
-  }
+        flags_(kArcValueFlags) {}
 
-  bool Done() const { return pos_ >= num_arcs_; }
+  bool Done() const { return pos_ >= state_.NumArcs(); }
 
   const Arc &Value() const {
-    arc_ = compactor_->Expand(state_, compacts_[pos_], flags_);
+    arc_ = state_.GetArc(pos_, flags_);
     return arc_;
   }
 
@@ -1116,102 +1323,13 @@ class ArcIterator<CompactFst<
   }
 
  private:
-  const Compactor *compactor_;  // Borrowed reference.
-  StateId state_;
-  const Element *compacts_;  // Borrowed reference.
+  State state_;
   size_t pos_;
-  size_t num_arcs_;
   mutable Arc arc_;
   uint32 flags_;
 };
 
-// // Specialization for CompactFst.
-// // This is an optionally caching arc iterator.
-// // TODO(allauzen): implements the kArcValueFlags, the current
-// /// implementation only implements the kArcNoCache flag.
-// template <class A, class C, class U>
-// class ArcIterator<CompactFst<A, C, U>> {
-//  public:
-//   using StateId = typename A::StateId;
-//
-//   ArcIterator(const CompactFst<A, C, U> &fst, StateId s)
-//       : fst_(fst), state_(s), pos_(0), num_arcs_(0), offset_(0),
-//         flags_(kArcValueFlags) {
-//     cache_data_.ref_count = 0;
-//
-//     if (fst_.GetImpl()->HasArcs(state_)) {
-//       fst_.GetImpl()->InitArcIterator(s, &cache_data_);
-//       num_arcs_ = cache_data_.narcs;
-//       return;
-//     }
-//
-//     const C *compactor = fst_.GetImpl()->GetCompactor();
-//     const DefaultCompactStore<A, C, U> *data = fst_.GetImpl()->Data();
-//     if (compactor->Size() == -1) {  // Variable out-degree compactor
-//       offset_ = data->States(s);
-//       num_arcs_ = data->States(s + 1) - offset_;
-//     } else {  // Fixed out-degree compactor
-//       offset_ =  s * compactor->Size();
-//       num_arcs_ = compactor->Size();
-//     }
-//     if (num_arcs_ > 0) {
-//       const A &arc = fst_.GetImpl()->ComputeArc(s, offset_);
-//       if (arc.ilabel == kNoStateId) {
-//         ++offset_;
-//         --num_arcs_;
-//       }
-//     }
-//   }
-//
-//   ~ArcIterator() {
-//     if (cache_data_.ref_count)
-//       --(*cache_data_.ref_count);
-//   }
-//
-//   bool Done() const { return pos_ >= num_arcs_; }
-//
-//   const A& Value() const {
-//     if (cache_data_.ref_count == 0) {
-//       if (flags_ & kArcNoCache) {
-//         arc_ = fst_.GetImpl()->ComputeArc(state_, pos_ + offset_);
-//         return arc_;
-//       } else {
-//         fst_.GetImpl()->InitArcIterator(state_, &cache_data_);
-//       }
-//     }
-//     return cache_data_.arcs[pos_];
-//   }
-//
-//   void Next() { ++pos_; }
-//
-//   size_t Position() const { return pos_; }
-//
-//   void Reset() { pos_ = 0;  }
-//
-//   void Seek(size_t pos) { pos_ = pos; }
-//
-//   uint32 Flags() const { return flags_; }
-//
-//   void SetFlags(uint32 f, uint32 m) {
-//     flags_ &= ~m;
-//     flags_ |= f;
-//
-//     if (!(flags_ & kArcNoCache) && cache_data_.ref_count == 0)
-//       fst_.GetImpl()->InitArcIterator(state_, &cache_data_);
-//   }
-//
-//  private:
-//   mutable const CompactFst<A, C, U> &fst_;
-//   StateId state_;
-//   size_t pos_;
-//   size_t num_arcs_;
-//   size_t offset_;
-//   uint32 flags_;
-//   mutable A arc_;
-//   mutable ArcIteratorData<A> cache_data_;
-// };
-
-// Compactor for unweighted string FSTs.
+// ArcCompactor for unweighted string FSTs.
 template <class A>
 class StringCompactor {
  public:
@@ -1240,8 +1358,8 @@ class StringCompactor {
   }
 
   static const string &Type() {
-    static const string type = "string";
-    return type;
+    static const string *const type = new string("string");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
@@ -1251,7 +1369,7 @@ class StringCompactor {
   }
 };
 
-// Compactor for weighted string FSTs.
+// ArcCompactor for weighted string FSTs.
 template <class A>
 class WeightedStringCompactor {
  public:
@@ -1281,8 +1399,8 @@ class WeightedStringCompactor {
   }
 
   static const string &Type() {
-    static const string type = "weighted_string";
-    return type;
+    static const string *const type = new string("weighted_string");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
@@ -1292,7 +1410,7 @@ class WeightedStringCompactor {
   }
 };
 
-// Compactor for unweighted acceptor FSTs.
+// ArcCompactor for unweighted acceptor FSTs.
 template <class A>
 class UnweightedAcceptorCompactor {
  public:
@@ -1321,8 +1439,8 @@ class UnweightedAcceptorCompactor {
   }
 
   static const string &Type() {
-    static const string type = "unweighted_acceptor";
-    return type;
+    static const string *const type = new string("unweighted_acceptor");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
@@ -1332,7 +1450,7 @@ class UnweightedAcceptorCompactor {
   }
 };
 
-// Compactor for weighted acceptor FSTs.
+// ArcCompactor for weighted acceptor FSTs.
 template <class A>
 class AcceptorCompactor {
  public:
@@ -1362,8 +1480,8 @@ class AcceptorCompactor {
   }
 
   static const string &Type() {
-    static const string type = "acceptor";
-    return type;
+    static const string *const type = new string("acceptor");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
@@ -1373,7 +1491,7 @@ class AcceptorCompactor {
   }
 };
 
-// Compactor for unweighted FSTs.
+// ArcCompactor for unweighted FSTs.
 template <class A>
 class UnweightedCompactor {
  public:
@@ -1403,8 +1521,8 @@ class UnweightedCompactor {
   }
 
   static const string &Type() {
-    static const string type = "unweighted";
-    return type;
+    static const string *const type = new string("unweighted");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
index 9bd2e81..d483cc9 100644 (file)
@@ -246,7 +246,7 @@ class ArcIterator<ComplementFst<Arc>> : public ArcIteratorBase<Arc> {
     pos_ = a;
   }
 
-  constexpr uint32 Flags() const final { return kArcValueFlags; }
+  uint32 Flags() const final { return kArcValueFlags; }
 
   void SetFlags(uint32, uint32) final {}
 
index 323f953..bf91bcb 100644 (file)
@@ -75,8 +75,9 @@ struct ComposeFstImplOptions : public CacheImplOptions<CacheStore> {
   M2 *matcher2;    // FST2 matcher.
   Filter *filter;  // Composition filter (see compose-filter.h).
   StateTable
-      *state_table;      // Composition state table (see compose-state-table.h).
-  bool own_state_table;  // ComposeFstImpl takes ownership of 'state_table'?
+    *state_table;        // Composition state table (see compose-state-table.h).
+  bool own_state_table;   // ComposeFstImpl takes ownership of 'state_table'?
+  bool allow_noncommute;  // Allow non-commutative weights
 
   explicit ComposeFstImplOptions(const CacheOptions &opts,
                                  M1 *matcher1 = nullptr, M2 *matcher2 = nullptr,
@@ -87,7 +88,8 @@ struct ComposeFstImplOptions : public CacheImplOptions<CacheStore> {
         matcher2(matcher2),
         filter(filter),
         state_table(state_table),
-        own_state_table(true) {}
+        own_state_table(true),
+        allow_noncommute(false) {}
 
   explicit ComposeFstImplOptions(const CacheImplOptions<CacheStore> &opts,
                                  M1 *matcher1 = nullptr, M2 *matcher2 = nullptr,
@@ -98,14 +100,16 @@ struct ComposeFstImplOptions : public CacheImplOptions<CacheStore> {
         matcher2(matcher2),
         filter(filter),
         state_table(state_table),
-        own_state_table(true) {}
+        own_state_table(true),
+        allow_noncommute(false) {}
 
   ComposeFstImplOptions()
       : matcher1(nullptr),
         matcher2(nullptr),
         filter(nullptr),
         state_table(nullptr),
-        own_state_table(true) {}
+        own_state_table(true),
+        allow_noncommute(false) {}
 };
 
 namespace internal {
@@ -616,9 +620,7 @@ class ComposeFst
     auto impl = std::make_shared<
         internal::ComposeFstImpl<CacheStore, Filter, StateTuple>>(fst1, fst2,
                                                                   opts);
-    // TODO(kbg): Make this a compile-time static_assert once all weight
-    // properties are made constexpr for all weight types.
-    if (!(Weight::Properties() & kCommutative)) {
+    if (!(Weight::Properties() & kCommutative) && !opts.allow_noncommute) {
       const auto props1 = fst1.Properties(kUnweighted, true);
       const auto props2 = fst2.Properties(kUnweighted, true);
       if (!(props1 & kUnweighted) && !(props2 & kUnweighted)) {
index 698326d..a3ad794 100644 (file)
@@ -7,9 +7,12 @@
 #ifndef FST_LIB_CONST_FST_H_
 #define FST_LIB_CONST_FST_H_
 
+#include <climits>
 #include <string>
 #include <vector>
 
+// Google-only...
+// ...Google-only
 #include <fst/log.h>
 
 #include <fst/expanded-fst.h>
@@ -52,9 +55,7 @@ class ConstFstImpl : public FstImpl<A> {
         start_(kNoStateId) {
     string type = "const";
     if (sizeof(Unsigned) != sizeof(uint32)) {
-      string size;
-      Int64ToStr(8 * sizeof(Unsigned), &size);
-      type += size;
+      type += std::to_string(CHAR_BIT * sizeof(Unsigned));
     }
     SetType(type);
     SetProperties(kNullProperties | kStaticProperties);
@@ -147,9 +148,7 @@ ConstFstImpl<Arc, Unsigned>::ConstFstImpl(const Fst<Arc> &fst)
     : nstates_(0), narcs_(0) {
   string type = "const";
   if (sizeof(Unsigned) != sizeof(uint32)) {
-    string size;
-    Int64ToStr(sizeof(Unsigned) * 8, &size);
-    type += size;
+    type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
   SetType(type);
   SetInputSymbols(fst.InputSymbols());
@@ -358,9 +357,7 @@ bool ConstFst<Arc, Unsigned>::WriteFst(const FST &fst, std::ostream &strm,
   hdr.SetNumArcs(num_arcs);
   string type = "const";
   if (sizeof(Unsigned) != sizeof(uint32)) {
-    string size;
-    Int64ToStr(8 * sizeof(Unsigned), &size);
-    type += size;
+    type += std::to_string(CHAR_BIT * sizeof(Unsigned));
   }
   const auto properties =
       fst.Properties(kCopyProperties, true) |
@@ -394,6 +391,14 @@ bool ConstFst<Arc, Unsigned>::WriteFst(const FST &fst, std::ostream &strm,
     for (ArcIterator<FST> aiter(fst, siter.Value()); !aiter.Done();
          aiter.Next()) {
       const auto &arc = aiter.Value();
+// Google-only...
+#ifdef MEMORY_SANITIZER
+      // arc may contain padding which has unspecified contents. Tell MSAN to
+      // not complain about it when writing it to a file.
+      ANNOTATE_MEMORY_IS_INITIALIZED(reinterpret_cast<const char *>(&arc),
+                                     sizeof(arc));
+#endif
+      // ...Google-only
       strm.write(reinterpret_cast<const char *>(&arc), sizeof(arc));
     }
   }
index adc7280..d476dd1 100644 (file)
@@ -51,8 +51,8 @@ struct LabelCommonDivisor {
   using Weight = StringWeight<Label, S>;
 
   Weight operator()(const Weight &w1, const Weight &w2) const {
-    StringWeightIterator<Label, S> iter1(w1);
-    StringWeightIterator<Label, S> iter2(w2);
+    typename Weight::Iterator iter1(w1);
+    typename Weight::Iterator iter2(w2);
     if (!(StringWeight<Label, S>::Properties() & kLeftSemiring)) {
       FSTERROR() << "LabelCommonDivisor: Weight needs to be left semiring";
       return Weight::NoWeight();
@@ -85,7 +85,7 @@ class GallicCommonDivisor {
   }
 
  private:
-  LabelCommonDivisor<Label, GALLIC_STRING_TYPE(G)> label_common_divisor_;
+  LabelCommonDivisor<Label, GallicStringType(G)> label_common_divisor_;
   CommonDivisor weight_common_divisor_;
 };
 
index a9d6313..d55fdc1 100644 (file)
@@ -321,7 +321,7 @@ class EncodeMapper {
   }
 
   bool Write(const string &filename) const {
-    std::ofstream strm(filename.c_str(),
+    std::ofstream strm(filename,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm) {
       LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
@@ -338,7 +338,7 @@ class EncodeMapper {
 
   static EncodeMapper<Arc> *Read(const string &filename,
                                  EncodeType type = ENCODE) {
-    std::ifstream strm(filename.c_str(),
+    std::ifstream strm(filename,
                             std::ios_base::in | std::ios_base::binary);
     if (!strm) {
       LOG(ERROR) << "EncodeMap: Can't open file: " << filename;
index 87c031e..f7ecae7 100644 (file)
@@ -61,7 +61,7 @@ class ExpandedFst : public Fst<A> {
   // Empty filename reads from standard input.
   static ExpandedFst<Arc> *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
@@ -139,7 +139,7 @@ class ImplToExpandedFst : public ImplToFst<Impl, FST> {
   // Empty filename reads from standard input.
   static Impl *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << filename;
index 8ffb996..f970fc9 100644 (file)
@@ -73,8 +73,9 @@ class ExpectationWeight : public PairWeight<X1, X2> {
   }
 
   static const string &Type() {
-    static const string type = "expectation_" + X1::Type() + "_" + X2::Type();
-    return type;
+    static const string *const type =
+        new string("expectation_" + X1::Type() + "_" + X2::Type());
+    return *type;
   }
 
   PairWeight<X1, X2> Quantize(float delta = kDelta) const {
index 1d1bd4d..c6b7d91 100644 (file)
@@ -13,9 +13,9 @@
 #include <vector>
 
 #include <fst/compat.h>
-#include <fstream>
 #include <fst/extensions/compress/elias.h>
 #include <fst/extensions/compress/gzfile.h>
+#include <fstream>
 
 #include <fst/encode.h>
 #include <fst/expanded-fst.h>
@@ -33,6 +33,36 @@ 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.
+template <class Var, class Edge>
+bool ExpandLZCode(const std::vector<std::pair<Var, Edge>> &code,
+                  std::vector<std::vector<Edge>> *expanded_code) {
+  expanded_code->resize(code.size());
+  for (int i = 0; i < code.size(); ++i) {
+    if (code[i].first > i) {
+      LOG(ERROR) << "ExpandLZCode: Not a valid code";
+      return false;
+    }
+    if (code[i].first == 0) {
+      (*expanded_code)[i].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;
+    }
+  }
+  return true;
+}
+
+}  // 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
@@ -380,8 +410,7 @@ void Compressor<Arc>::EncodeProcessedFst(const ExpandedFst<Arc> &fst,
     }
 
     // Reading the states
-    for (ArcIterator<Fst<Arc>> aiter(fst, state); !aiter.Done();
-         aiter.Next()) {
+    for (ArcIterator<Fst<Arc>> aiter(fst, state); !aiter.Done(); aiter.Next()) {
       Arc arc = aiter.Value();
       if (arc.nextstate > seen_states) {  // RILEY: > or >= ?
         ++seen_states;
@@ -795,7 +824,7 @@ bool Compress(const Fst<Arc> &fst, const string &file_name,
     } else {
       std::stringstream strm;
       Compress(fst, strm);
-      OGzFile gzfile(file_name.c_str());
+      OGzFile gzfile(file_name);
       if (!gzfile) {
         LOG(ERROR) << "Compress: Can't open file: " << file_name;
         return false;
@@ -809,7 +838,7 @@ bool Compress(const Fst<Arc> &fst, const string &file_name,
   } else if (file_name.empty()) {
     Compress(fst, std::cout);
   } else {
-    std::ofstream strm(file_name.c_str(),
+    std::ofstream strm(file_name,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm) {
       LOG(ERROR) << "Compress: Can't open file: " << file_name;
@@ -840,7 +869,7 @@ bool Decompress(const string &file_name, MutableFst<Arc> *fst,
         return false;
       }
     } else {
-      IGzFile gzfile(file_name.c_str());
+      IGzFile gzfile(file_name);
       if (!gzfile) {
         LOG(ERROR) << "Decompress: Can't open file: " << file_name;
         return false;
@@ -854,7 +883,7 @@ bool Decompress(const string &file_name, MutableFst<Arc> *fst,
   } else if (file_name.empty()) {
     Decompress(std::cin, "stdin", fst);
   } else {
-    std::ifstream strm(file_name.c_str(),
+    std::ifstream strm(file_name,
                             std::ios_base::in | std::ios_base::binary);
     if (!strm) {
       LOG(ERROR) << "Decompress: Can't open file: " << file_name;
index c1c5af4..39c4f9b 100644 (file)
@@ -33,11 +33,13 @@ class GzFile {
   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) {
   }
+
   // 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); }
@@ -69,8 +71,11 @@ class 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 int fd) : gz_(GzFile(fd, mode_)) {}
+
   inline bool operator!() const { return !gz_; }
 
   void write(const stringstream &ssbuf) {
@@ -87,7 +92,9 @@ class OGzFile {
 class IGzFile {
  public:
   explicit IGzFile(const string &filename) : IGzFile(filename.c_str()) {}
+
   explicit IGzFile(const char *filename) : gz_(GzFile(filename, mode_)) {}
+
   explicit IGzFile(const int fd) : gz_(GzFile(fd, mode_)) {}
 
   inline bool operator!() const { return !gz_; }
index f1ca75f..5804584 100644 (file)
@@ -165,6 +165,20 @@ void FarInfo(const std::vector<string> &filenames, const string &arc_type,
              const string &begin_key, const string &end_key,
              const bool list_fsts);
 
+using GetFarInfoArgs =
+    args::Package<const std::vector<string> &, const string &, const string &,
+                  const bool, FarInfoData *>;
+
+template <class Arc>
+void GetFarInfo(GetFarInfoArgs *args) {
+  fst::GetFarInfo<Arc>(args->arg1, args->arg2, args->arg3, args->arg4,
+                           args->arg5);
+}
+
+void GetFarInfo(const std::vector<string> &filenames, const string &arc_type,
+                const string &begin_key, const string &end_key,
+                const bool list_fsts, FarInfoData *);
+
 using FarIsomorphicInnerArgs =
     args::Package<const string &, const string &, float, const string &,
                   const string &>;
@@ -247,6 +261,7 @@ void FarPrintStrings(const std::vector<string> &ifilenames,
   REGISTER_FST_OPERATION(FarExtract, ArcType, FarExtractArgs);               \
   REGISTER_FST_OPERATION(FarInfo, ArcType, FarInfoArgs);                     \
   REGISTER_FST_OPERATION(FarIsomorphic, ArcType, FarIsomorphicArgs);         \
-  REGISTER_FST_OPERATION(FarPrintStrings, ArcType, FarPrintStringsArgs)
+  REGISTER_FST_OPERATION(FarPrintStrings, ArcType, FarPrintStringsArgs);     \
+  REGISTER_FST_OPERATION(GetFarInfo, ArcType, GetFarInfoArgs)
 
 #endif  // FST_EXTENSIONS_FAR_FARSCRIPT_H_
index 6121dd1..0391c1f 100644 (file)
@@ -31,66 +31,83 @@ void AccumulateStatesAndArcs(const Fst<Arc> &fst, size_t *nstate, size_t *narc,
 struct KeyInfo {
   string key;
   string type;
-  size_t nstate;
-  size_t narc;
-  size_t nfinal;
-
-  KeyInfo(string k, string t, int64 ns = 0, int64 na = 0, int nf = 0)
-      : key(std::move(k)),
-        type(std::move(t)),
-        nstate(ns),
-        narc(na),
-        nfinal(nf) {}
+  size_t nstate = 0;
+  size_t narc = 0;
+  size_t nfinal = 0;
 };
 
-template <class Arc>
-void FarInfo(const std::vector<string> &filenames, const string &begin_key,
-             const string &end_key, const bool list_fsts) {
-  std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(filenames));
-  if (!reader) return;
-  if (!begin_key.empty()) reader->Find(begin_key);
-  auto *infos = list_fsts ? new std::vector<KeyInfo>() : nullptr;
+struct FarInfoData {
+  std::vector<KeyInfo> key_infos;
+  string far_type;
+  string arc_type;
   size_t nfst = 0;
   size_t nstate = 0;
   size_t narc = 0;
   size_t nfinal = 0;
   std::set<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) {
+  *far_info = FarInfoData();
+  std::unique_ptr<FarReader<Arc>> reader(FarReader<Arc>::Open(filenames));
+  if (!reader) {
+    LOG(ERROR) << "GetFarInfo: failed to create far reader.";
+    return;
+  }
+  if (!begin_key.empty()) reader->Find(begin_key);
+
   for (; !reader->Done(); reader->Next()) {
     const auto &key = reader->GetKey();
     if (!end_key.empty() && end_key < key) break;
-    ++nfst;
+    ++far_info->nfst;
     const auto *fst = reader->GetFst();
-    fst_types.insert(fst->Type());
-    if (infos) {
-      KeyInfo info(key, fst->Type());
+    far_info->fst_types.insert(fst->Type());
+    if (list_fsts) {
+      KeyInfo info;
+      info.key = key;
+      info.type = fst->Type();
       AccumulateStatesAndArcs(*fst, &info.nstate, &info.narc, &info.nfinal);
-      nstate += info.nstate;
-      narc += info.narc;
-      nfinal += info.nfinal;
-      infos->push_back(info);
+      far_info->nstate += info.nstate;
+      far_info->narc += info.narc;
+      far_info->nfinal += info.nfinal;
+      far_info->key_infos.push_back(info);
     } else {
-      AccumulateStatesAndArcs(*fst, &nstate, &narc, &nfinal);
+      AccumulateStatesAndArcs(*fst, &far_info->nstate, &far_info->narc,
+                              &far_info->nfinal);
     }
   }
-  if (!infos) {
-    std::cout << std::left << std::setw(50) << "far type"
-              << GetFarTypeString(reader->Type()) << std::endl;
+  far_info->far_type = GetFarTypeString(reader->Type());
+  far_info->arc_type = Arc::Type();
+}
+
+template <class Arc>
+void FarInfo(const std::vector<string> &filenames, const string &begin_key,
+             const string &end_key, const bool list_fsts) {
+  FarInfoData info;
+  GetFarInfo<Arc>(filenames, begin_key, end_key, list_fsts, &info);
+  if (!list_fsts) {
+    std::cout << std::left << std::setw(50) << "far type" << info.far_type
+              << std::endl;
     std::cout << std::left << std::setw(50) << "arc type" << Arc::Type()
               << std::endl;
     std::cout << std::left << std::setw(50) << "fst type";
-    for (std::set<string>::const_iterator iter = fst_types.begin();
-         iter != fst_types.end(); ++iter) {
-      if (iter != fst_types.begin()) std::cout << ",";
+    for (auto iter = info.fst_types.begin(); iter != info.fst_types.end();
+         ++iter) {
+      if (iter != info.fst_types.begin()) std::cout << ",";
       std::cout << *iter;
     }
     std::cout << std::endl;
-    std::cout << std::left << std::setw(50) << "# of FSTs" << nfst << std::endl;
-    std::cout << std::left << std::setw(50) << "total # of states" << nstate
+    std::cout << std::left << std::setw(50) << "# of FSTs" << info.nfst
               << std::endl;
-    std::cout << std::left << std::setw(50) << "total # of arcs" << narc
+    std::cout << std::left << std::setw(50) << "total # of states"
+              << info.nstate << std::endl;
+    std::cout << std::left << std::setw(50) << "total # of arcs" << info.narc
               << std::endl;
     std::cout << std::left << std::setw(50) << "total # of final states"
-              << nfinal << std::endl;
+              << info.nfinal << std::endl;
   } else {
     // FIXME(kbg): Grok, then document this.
     int wkey = 10;
@@ -98,30 +115,29 @@ void FarInfo(const std::vector<string> &filenames, const string &begin_key,
     int wnstate = 14;
     int wnarc = 12;
     int wnfinal = 20;
-    for (size_t i = 0; i < infos->size(); ++i) {
-      const auto &info = (*infos)[i];
-      if (info.key.size() + 2 > wkey) wkey = info.key.size() + 2;
-      if (info.type.size() + 2 > wtype) wtype = info.type.size() + 2;
-      if (ceil(log10(info.nstate)) + 2 > wnstate) {
-        wnstate = ceil(log10(info.nstate)) + 2;
+    for (const auto &key_info : info.key_infos) {
+      if (key_info.key.size() + 2 > wkey) wkey = key_info.key.size() + 2;
+      if (key_info.type.size() + 2 > wtype) wtype = key_info.type.size() + 2;
+      if (ceil(log10(key_info.nstate)) + 2 > wnstate) {
+        wnstate = ceil(log10(key_info.nstate)) + 2;
       }
-      if (ceil(log10(info.narc)) + 2 > wnarc) {
-        wnarc = ceil(log10(info.narc)) + 2;
+      if (ceil(log10(key_info.narc)) + 2 > wnarc) {
+        wnarc = ceil(log10(key_info.narc)) + 2;
       }
-      if (ceil(log10(info.nfinal)) + 2 > wnfinal) {
-        wnfinal = ceil(log10(info.nfinal)) + 2;
+      if (ceil(log10(key_info.nfinal)) + 2 > wnfinal) {
+        wnfinal = ceil(log10(key_info.nfinal)) + 2;
       }
     }
     std::cout << std::left << std::setw(wkey) << "key" << std::setw(wtype)
               << "type" << std::right << std::setw(wnstate) << "# of states"
               << std::setw(wnarc) << "# of arcs" << std::setw(wnfinal)
               << "# of final states" << std::endl;
-    for (size_t i = 0; i < infos->size(); ++i) {
-      const auto &info = (*infos)[i];
-      std::cout << std::left << std::setw(wkey) << info.key << std::setw(wtype)
-                << info.type << std::right << std::setw(wnstate) << info.nstate
-                << std::setw(wnarc) << info.narc << std::setw(wnfinal)
-                << info.nfinal << std::endl;
+    for (const auto &key_info : info.key_infos) {
+      std::cout << std::left << std::setw(wkey) << key_info.key
+                << std::setw(wtype) << key_info.type << std::right
+                << std::setw(wnstate) << key_info.nstate << std::setw(wnarc)
+                << key_info.narc << std::setw(wnfinal) << key_info.nfinal
+                << std::endl;
     }
   }
 }
index a837087..a2c19e7 100644 (file)
@@ -495,7 +495,7 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
 
   static LinearTaggerFst<A> *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "LinearTaggerFst::Read: Can't open file: " << filename;
@@ -515,7 +515,7 @@ class LinearTaggerFst : public ImplToFst<internal::LinearTaggerFstImpl<A>> {
 
   bool Write(const string &filename) const override {
     if (!filename.empty()) {
-      std::ofstream strm(filename.c_str(),
+      std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "LinearTaggerFst::Write: Can't open file: " << filename;
@@ -952,7 +952,7 @@ class LinearClassifierFst
 
   static LinearClassifierFst<A> *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "LinearClassifierFst::Read: Can't open file: "
@@ -974,7 +974,7 @@ class LinearClassifierFst
 
   bool Write(const string &filename) const override {
     if (!filename.empty()) {
-      std::ofstream strm(filename.c_str(),
+      std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "ProdLmFst::Write: Can't open file: " << filename;
index cc112d3..512fcfa 100644 (file)
@@ -151,9 +151,9 @@ template <class Arc, typename Arc::Label nlevels>
 void MPdtInfo<Arc, nlevels>::Print() {
   const auto old = std::cout.setf(std::ios::left);
   std::cout.width(50);
-  std::cout << "fst type" << FstType().c_str() << std::endl;
+  std::cout << "fst type" << FstType() << std::endl;
   std::cout.width(50);
-  std::cout << "arc type" << ArcType().c_str() << std::endl;
+  std::cout << "arc type" << ArcType() << std::endl;
   std::cout.width(50);
   std::cout << "# of states" << NumStates() << std::endl;
   std::cout.width(50);
index e66a620..532f458 100644 (file)
@@ -384,7 +384,7 @@ class NGramFst : public ImplToExpandedFst<internal::NGramFstImpl<A>> {
 
   static NGramFst<A> *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm.good()) {
         LOG(ERROR) << "NGramFst::Read: Can't open file: " << filename;
index 38bc5bb..3de5477 100644 (file)
@@ -121,9 +121,9 @@ template <class Arc>
 void PrintPdtInfo(const PdtInfo<Arc> &info) {
   const auto old = std::cout.setf(std::ios::left);
   std::cout.width(50);
-  std::cout << "fst type" << info.FstType().c_str() << std::endl;
+  std::cout << "fst type" << info.FstType() << std::endl;
   std::cout.width(50);
-  std::cout << "arc type" << info.ArcType().c_str() << std::endl;
+  std::cout << "arc type" << info.ArcType() << std::endl;
   std::cout.width(50);
   std::cout << "# of states" << info.NumStates() << std::endl;
   std::cout.width(50);
index 948e997..70a2f51 100644 (file)
@@ -107,9 +107,10 @@ class StringFactor {
   void Next() { done_ = true; }
 
   std::pair<StringWeight<Label, S>, StringWeight<Label, S>> Value() const {
-    StringWeightIterator<Label, S> siter(weight_);
-    StringWeight<Label, S> w1(siter.Value());
-    StringWeight<Label, S> w2;
+    using Weight = StringWeight<Label, S>;
+    typename Weight::Iterator siter(weight_);
+    Weight w1(siter.Value());
+    Weight w2;
     for (siter.Next(); !siter.Done(); siter.Next()) w2.PushBack(siter.Value());
     return std::make_pair(w1, w2);
   }
@@ -135,7 +136,7 @@ class GallicFactor {
   void Next() { done_ = true; }
 
   std::pair<GW, GW> Value() const {
-    StringFactor<Label, GALLIC_STRING_TYPE(G)> siter(weight_.Value1());
+    StringFactor<Label, GallicStringType(G)> siter(weight_.Value1());
     GW w1(siter.Value().first, weight_.Value2());
     GW w2(siter.Value().second, W::One());
     return std::make_pair(w1, w2);
@@ -168,7 +169,7 @@ class GallicFactor<Label, W, GALLIC> {
 
   std::pair<GW, GW> Value() const {
     const auto weight = iter_.Value();
-    StringFactor<Label, GALLIC_STRING_TYPE(GALLIC_RESTRICT)> siter(
+    StringFactor<Label, GallicStringType(GALLIC_RESTRICT)> siter(
         weight.Value1());
     GRW w1(siter.Value().first, weight.Value2());
     GRW w2(siter.Value().second, W::One());
index b99f71f..965b3c9 100644 (file)
@@ -136,7 +136,7 @@ inline std::ostream &operator<<(std::ostream &strm,
     return strm << "Infinity";
   } else if (w.Value() == FloatLimits<T>::NegInfinity()) {
     return strm << "-Infinity";
-  } else if (w.Value() != w.Value()) {  // Fails for NaN.
+  } else if (w.Value() != w.Value()) {  // Fails for IEEE NaN.
     return strm << "BadNumber";
   } else {
     return strm << w.Value();
@@ -170,6 +170,7 @@ class TropicalWeightTpl : public FloatWeightTpl<T> {
   using typename FloatWeightTpl<T>::ValueType;
   using FloatWeightTpl<T>::Value;
   using ReverseWeight = TropicalWeightTpl<T>;
+  using Limits = FloatLimits<T>;
 
   constexpr TropicalWeightTpl() : FloatWeightTpl<T>() {}
 
@@ -179,7 +180,7 @@ class TropicalWeightTpl : public FloatWeightTpl<T> {
       : FloatWeightTpl<T>(weight) {}
 
   static const TropicalWeightTpl<T> &Zero() {
-    static const TropicalWeightTpl zero(FloatLimits<T>::PosInfinity());
+    static const TropicalWeightTpl zero(Limits::PosInfinity());
     return zero;
   }
 
@@ -189,24 +190,24 @@ class TropicalWeightTpl : public FloatWeightTpl<T> {
   }
 
   static const TropicalWeightTpl<T> &NoWeight() {
-    static const TropicalWeightTpl no_weight(FloatLimits<T>::NumberBad());
+    static const TropicalWeightTpl no_weight(Limits::NumberBad());
     return no_weight;
   }
 
   static const string &Type() {
-    static const string type =
-        string("tropical") + FloatWeightTpl<T>::GetPrecisionString();
-    return type;
+    static const string *const type =
+        new string(string("tropical") +
+                   FloatWeightTpl<T>::GetPrecisionString());
+    return *type;
   }
 
   bool Member() const {
     // First part fails for IEEE NaN.
-    return Value() == Value() && Value() != FloatLimits<T>::NegInfinity();
+    return Value() == Value() && Value() != Limits::NegInfinity();
   }
 
   TropicalWeightTpl<T> Quantize(float delta = kDelta) const {
-    if (Value() == FloatLimits<T>::NegInfinity() ||
-        Value() == FloatLimits<T>::PosInfinity() || Value() != Value()) {
+    if (!Member() || Value() == Limits::PosInfinity()) {
       return *this;
     } else {
       return TropicalWeightTpl<T>(floor(Value() / delta + 0.5F) * delta);
@@ -243,11 +244,13 @@ inline TropicalWeightTpl<double> Plus(const TropicalWeightTpl<double> &w1,
 template <class T>
 inline TropicalWeightTpl<T> Times(const TropicalWeightTpl<T> &w1,
                                   const TropicalWeightTpl<T> &w2) {
+  using Limits = FloatLimits<T>;
   if (!w1.Member() || !w2.Member()) return TropicalWeightTpl<T>::NoWeight();
-  T f1 = w1.Value(), f2 = w2.Value();
-  if (f1 == FloatLimits<T>::PosInfinity()) {
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f1 == Limits::PosInfinity()) {
     return w1;
-  } else if (f2 == FloatLimits<T>::PosInfinity()) {
+  } else if (f2 == Limits::PosInfinity()) {
     return w2;
   } else {
     return TropicalWeightTpl<T>(f1 + f2);
@@ -268,12 +271,14 @@ template <class T>
 inline TropicalWeightTpl<T> Divide(const TropicalWeightTpl<T> &w1,
                                    const TropicalWeightTpl<T> &w2,
                                    DivideType typ = DIVIDE_ANY) {
+  using Limits = FloatLimits<T>;
   if (!w1.Member() || !w2.Member()) return TropicalWeightTpl<T>::NoWeight();
-  T f1 = w1.Value(), f2 = w2.Value();
-  if (f2 == FloatLimits<T>::PosInfinity()) {
-    return FloatLimits<T>::NumberBad();
-  } else if (f1 == FloatLimits<T>::PosInfinity()) {
-    return FloatLimits<T>::PosInfinity();
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f2 == Limits::PosInfinity()) {
+    return Limits::NumberBad();
+  } else if (f1 == Limits::PosInfinity()) {
+    return Limits::PosInfinity();
   } else {
     return TropicalWeightTpl<T>(f1 - f2);
   }
@@ -304,6 +309,7 @@ class LogWeightTpl : public FloatWeightTpl<T> {
   using typename FloatWeightTpl<T>::ValueType;
   using FloatWeightTpl<T>::Value;
   using ReverseWeight = LogWeightTpl;
+  using Limits = FloatLimits<T>;
 
   constexpr LogWeightTpl() : FloatWeightTpl<T>() {}
 
@@ -313,7 +319,7 @@ class LogWeightTpl : public FloatWeightTpl<T> {
       : FloatWeightTpl<T>(weight) {}
 
   static const LogWeightTpl &Zero() {
-    static const LogWeightTpl zero(FloatLimits<T>::PosInfinity());
+    static const LogWeightTpl zero(Limits::PosInfinity());
     return zero;
   }
 
@@ -323,24 +329,23 @@ class LogWeightTpl : public FloatWeightTpl<T> {
   }
 
   static const LogWeightTpl &NoWeight() {
-    static const LogWeightTpl no_weight(FloatLimits<T>::NumberBad());
+    static const LogWeightTpl no_weight(Limits::NumberBad());
     return no_weight;
   }
 
   static const string &Type() {
-    static const string type =
-        string("log") + FloatWeightTpl<T>::GetPrecisionString();
-    return type;
+    static const string *const type =
+        new string(string("log") + FloatWeightTpl<T>::GetPrecisionString());
+    return *type;
   }
 
   bool Member() const {
     // First part fails for IEEE NaN.
-    return Value() == Value() && Value() != FloatLimits<T>::NegInfinity();
+    return Value() == Value() && Value() != Limits::NegInfinity();
   }
 
   LogWeightTpl<T> Quantize(float delta = kDelta) const {
-    if (Value() == FloatLimits<T>::NegInfinity() ||
-        Value() == FloatLimits<T>::PosInfinity() || Value() != Value()) {
+    if (!Member() || Value() == Limits::PosInfinity()) {
       return *this;
     } else {
       return LogWeightTpl<T>(floor(Value() / delta + 0.5F) * delta);
@@ -362,54 +367,18 @@ using Log64Weight = LogWeightTpl<double>;
 
 namespace internal {
 
-// -log(e^-x + e^-y) = x - LogPosExp(y - x)
-// Assumes x >= 0.0.
-inline double LogPosExp(double x) {
-  return std::log(1.0 + std::exp(-x));
-}
+// -log(e^-x + e^-y) = x - LogPosExp(y - x), assuming x >= 0.0.
+inline double LogPosExp(double x) { return log1p(exp(-x)); }
 
-// -log(e^-x - e^-y) = x - LogNegExp(y - x)
-// Assumes x >= 0.0.
-inline double LogNegExp(double x) {
-  return std::log(1.0 - std::exp(-x));
-}
-
-// Alternative LogPosExp that is more accurate for large x.
-// Assumes x >= 0.0.
-inline double AltLogPosExp(double x) {
-  double y = std::exp(-x);
-  if (y > kDelta) {
-    return std::log(1.0 + y);
-  } else {
-    // Mercator series
-    double y2 = y * y;
-    double y3 = y2 * y;
-    double y4 = y2 * y2;
-    return y - y2/2.0 + y3/3.0 - y4/4.0;
-  }
-}
-
-// Alternative LogNegExp that is more accurate for large x.
-// Assumes x > 0.0.
-inline double AltLogNegExp(double x) {
-  double y = std::exp(-x);
-  if (y > kDelta) {
-    return std::log(1.0 - y);
-  } else {
-    // Mercator series
-    double y2 = y * y;
-    double y3 = y2 * y;
-    double y4 = y2 * y2;
-    return -y - y2/2.0 - y3/3.0 - y4/4.0;
-  }
-}
+// -log(e^-x - e^-y) = x - LogNegExp(y - x), assuming x > 0.0.
+inline double LogNegExp(double x) { return log1p(-exp(-x)); }
 
 // a +_log b = -log(e^-a + e^-b) = KahanLogSum(a, b, ...).
 // Kahan compensated summation provides an error bound that is
 // independent of the number of addends. Assumes b >= a;
 // c is the compensation.
 inline double KahanLogSum(double a, double b, double *c) {
-  double y = -AltLogPosExp(b - a) - *c;
+  double y = -LogPosExp(b - a) - *c;
   double t = a + y;
   *c = (t - a) - y;
   return t;
@@ -420,7 +389,7 @@ inline double KahanLogSum(double a, double b, double *c) {
 // independent of the number of addends. Assumes b > a;
 // c is the compensation.
 inline double KahanLogDiff(double a, double b, double *c) {
-  double y = -AltLogNegExp(b - a) - *c;
+  double y = -LogNegExp(b - a) - *c;
   double t = a + y;
   *c = (t - a) - y;
   return t;
@@ -431,10 +400,12 @@ inline double KahanLogDiff(double a, double b, double *c) {
 template <class T>
 inline LogWeightTpl<T> Plus(const LogWeightTpl<T> &w1,
                             const LogWeightTpl<T> &w2) {
-  T f1 = w1.Value(), f2 = w2.Value();
-  if (f1 == FloatLimits<T>::PosInfinity()) {
+  using Limits = FloatLimits<T>;
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f1 == Limits::PosInfinity()) {
     return w2;
-  } else if (f2 == FloatLimits<T>::PosInfinity()) {
+  } else if (f2 == Limits::PosInfinity()) {
     return w1;
   } else if (f1 > f2) {
     return LogWeightTpl<T>(f2 - internal::LogPosExp(f1 - f2));
@@ -456,11 +427,13 @@ inline LogWeightTpl<double> Plus(const LogWeightTpl<double> &w1,
 template <class T>
 inline LogWeightTpl<T> Times(const LogWeightTpl<T> &w1,
                              const LogWeightTpl<T> &w2) {
+  using Limits = FloatLimits<T>;
   if (!w1.Member() || !w2.Member()) return LogWeightTpl<T>::NoWeight();
-  T f1 = w1.Value(), f2 = w2.Value();
-  if (f1 == FloatLimits<T>::PosInfinity()) {
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f1 == Limits::PosInfinity()) {
     return w1;
-  } else if (f2 == FloatLimits<T>::PosInfinity()) {
+  } else if (f2 == Limits::PosInfinity()) {
     return w2;
   } else {
     return LogWeightTpl<T>(f1 + f2);
@@ -481,12 +454,14 @@ template <class T>
 inline LogWeightTpl<T> Divide(const LogWeightTpl<T> &w1,
                               const LogWeightTpl<T> &w2,
                               DivideType typ = DIVIDE_ANY) {
+  using Limits = FloatLimits<T>;
   if (!w1.Member() || !w2.Member()) return LogWeightTpl<T>::NoWeight();
-  T f1 = w1.Value(), f2 = w2.Value();
-  if (f2 == FloatLimits<T>::PosInfinity()) {
-    return FloatLimits<T>::NumberBad();
-  } else if (f1 == FloatLimits<T>::PosInfinity()) {
-    return FloatLimits<T>::PosInfinity();
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  if (f2 == Limits::PosInfinity()) {
+    return Limits::NumberBad();
+  } else if (f1 == Limits::PosInfinity()) {
+    return Limits::PosInfinity();
   } else {
     return LogWeightTpl<T>(f1 - f2);
   }
@@ -509,7 +484,7 @@ inline LogWeightTpl<T> Power(const LogWeightTpl<T> &weight, T scalar) {
   return LogWeightTpl<T>(weight.Value() * scalar);
 }
 
-// Specialization using the Kahan compensated summation
+// Specialization using the Kahan compensated summation.
 template <class T>
 class Adder<LogWeightTpl<T>> {
  public:
@@ -520,10 +495,11 @@ class Adder<LogWeightTpl<T>> {
         c_(0.0) { }
 
   Weight Add(const Weight &w) {
-    T f = w.Value();
-    if (f == FloatLimits<T>::PosInfinity()) {
+  using Limits = FloatLimits<T>;
+    const T f = w.Value();
+    if (f == Limits::PosInfinity()) {
       return Sum();
-    } else if (sum_ == FloatLimits<T>::PosInfinity()) {
+    } else if (sum_ == Limits::PosInfinity()) {
       sum_ = f;
       c_ = 0.0;
     } else if (f > sum_) {
@@ -543,7 +519,7 @@ class Adder<LogWeightTpl<T>> {
 
  private:
   double sum_;
-  double c_;   // Kahan compensation
+  double c_;   // Kahan compensation.
 };
 
 // MinMax semiring: (min, max, inf, -inf).
@@ -552,8 +528,8 @@ class MinMaxWeightTpl : public FloatWeightTpl<T> {
  public:
   using typename FloatWeightTpl<T>::ValueType;
   using FloatWeightTpl<T>::Value;
-
   using ReverseWeight = MinMaxWeightTpl<T>;
+  using Limits = FloatLimits<T>;
 
   MinMaxWeightTpl() : FloatWeightTpl<T>() {}
 
@@ -563,35 +539,33 @@ class MinMaxWeightTpl : public FloatWeightTpl<T> {
       : FloatWeightTpl<T>(weight) {}
 
   static const MinMaxWeightTpl &Zero() {
-    static const MinMaxWeightTpl zero(FloatLimits<T>::PosInfinity());
+    static const MinMaxWeightTpl zero(Limits::PosInfinity());
     return zero;
   }
 
   static const MinMaxWeightTpl &One() {
-    static const MinMaxWeightTpl one(FloatLimits<T>::NegInfinity());
+    static const MinMaxWeightTpl one(Limits::NegInfinity());
     return one;
   }
 
   static const MinMaxWeightTpl &NoWeight() {
-    static const MinMaxWeightTpl no_weight(FloatLimits<T>::NumberBad());
+    static const MinMaxWeightTpl no_weight(Limits::NumberBad());
     return no_weight;
   }
 
   static const string &Type() {
-    static const string type =
-        string("minmax") + FloatWeightTpl<T>::GetPrecisionString();
-    return type;
+    static const string *const type =
+        new string(string("minmax") + FloatWeightTpl<T>::GetPrecisionString());
+    return *type;
   }
 
-  bool Member() const {
-    // Fails for IEEE NaN
-    return Value() == Value();
-  }
+  // Fails for IEEE NaN.
+  bool Member() const { return Value() == Value(); }
 
   MinMaxWeightTpl<T> Quantize(float delta = kDelta) const {
-    // If one of infinities, or a NaN
-    if (Value() == FloatLimits<T>::NegInfinity() ||
-        Value() == FloatLimits<T>::PosInfinity() || Value() != Value()) {
+    // If one of infinities, or a NaN.
+    if (!Member() ||
+        Value() == Limits::NegInfinity() || Value() == Limits::PosInfinity()) {
       return *this;
     } else {
       return MinMaxWeightTpl<T>(floor(Value() / delta + 0.5F) * delta);
@@ -712,14 +686,14 @@ class FloatWeightGenerate {
       : allow_zero_(allow_zero), num_random_weights_(num_random_weights) {}
 
   Weight operator()() const {
-    int n = rand() % (num_random_weights_ + allow_zero_);  // NOLINT
+    const int n = rand() % (num_random_weights_ + allow_zero_);  // NOLINT
     if (allow_zero_ && n == num_random_weights_) return Weight::Zero();
     return Weight(n);
   }
 
  private:
   // Permits Zero() and zero divisors.
-  bool allow_zero_;
+  const bool allow_zero_;
   // Number of alternative random weights.
   const size_t num_random_weights_;
 };
@@ -766,8 +740,9 @@ class WeightGenerate<MinMaxWeightTpl<T>> {
       : allow_zero_(allow_zero), num_random_weights_(num_random_weights) {}
 
   Weight operator()() const {
-    int n = (rand() % (2 * num_random_weights_ + allow_zero_)) -  // NOLINT
-            num_random_weights_;
+    const int n = (rand() %  // NOLINT
+                   (2 * num_random_weights_ + allow_zero_)) -
+                  num_random_weights_;
     if (allow_zero_ && n == num_random_weights_) {
       return Weight::Zero();
     } else if (n == -num_random_weights_) {
@@ -779,7 +754,7 @@ class WeightGenerate<MinMaxWeightTpl<T>> {
 
  private:
   // Permits Zero() and zero divisors.
-  bool allow_zero_;
+  const bool allow_zero_;
   // Number of alternative random weights.
   const size_t num_random_weights_;
 };
index 814a940..9f0cc3c 100644 (file)
@@ -254,7 +254,7 @@ class Fst {
   // results in reading from standard input.
   static Fst<Arc> *Read(const string &filename) {
     if (!filename.empty()) {
-      std::ifstream strm(filename.c_str(),
+      std::ifstream strm(filename,
                               std::ios_base::in | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "Fst::Read: Can't open file: " << filename;
@@ -301,7 +301,7 @@ class Fst {
  protected:
   bool WriteFile(const string &filename) const {
     if (!filename.empty()) {
-      std::ofstream strm(filename.c_str(),
+      std::ofstream strm(filename,
                                std::ios_base::out | std::ios_base::binary);
       if (!strm) {
         LOG(ERROR) << "Fst::Write: Can't open file: " << filename;
@@ -923,7 +923,9 @@ class ImplToFst : public FST {
 // (which excludes implementations with weight-dependent virtual methods).
 // Must be a friend of the FST classes involved (currently the concrete FSTs:
 // ConstFst, CompactFst, and VectorFst). This can only be safely used for arc
-// types that have identical storage characteristics.
+// types that have identical storage characteristics. As with an FST
+// copy constructor and Copy() method, this is a constant time operation
+// (but subject to copy-on-write if it is a MutableFst and modified).
 template <class IFST, class OFST>
 void Cast(const IFST &ifst, OFST *ofst) {
   using OImpl = typename OFST::Impl;
index 8892273..2e6d4c6 100644 (file)
@@ -65,7 +65,7 @@ class Heap {
     }
   }
 
-  // Returns the greatest (max=true) / least (max=false) value.
+  // Returns the least value.
   Value Pop() {
     Value top = values_.front();
     Swap(0, size_-1);
@@ -74,8 +74,8 @@ class Heap {
     return top;
   }
 
-  // Returns the greatest (max=true) / least (max=false) value w.r.t.
-  // the comparison function from the heap.
+  // Returns the least value w.r.t.  the comparison function from the
+  // heap.
   const Value &Top() const { return values_.front(); }
 
   // Returns the element for the given key.
index 28072f4..56e2bff 100644 (file)
@@ -75,8 +75,9 @@ class LexicographicWeight : public PairWeight<W1, W2> {
   }
 
   static const string &Type() {
-    static const string type = W1::Type() + "_LT_" + W2::Type();
-    return type;
+    static const string *const type =
+        new string(W1::Type() + "_LT_" + W2::Type());
+    return *type;
   }
 
   bool Member() const {
index 7fe9564..bbc72c7 100644 (file)
@@ -34,7 +34,7 @@ class MappedFile {
 
   const void *data() const { return region_.data; }
 
-  // Returns a MappedFile object that contains the contents of the input strea
+  // Returns a MappedFile object that contains the contents of the input stream
   // strm starting from the current file position with size bytes. The memorymap
   // bool is advisory, and Map will default to allocating and reading. The
   // source argument needs to contain the filename that was used to open the
index 90aea94..6577b43 100644 (file)
@@ -129,7 +129,7 @@ class MutableFst : public ExpandedFst<A> {
                                const string &convert_type = "vector") {
     if (convert == false) {
       if (!filename.empty()) {
-        std::ifstream strm(filename.c_str(),
+        std::ifstream strm(filename,
                                 std::ios_base::in | std::ios_base::binary);
         if (!strm) {
           LOG(ERROR) << "MutableFst::Read: Can't open file: " << filename;
index 422954f..937897f 100644 (file)
@@ -54,9 +54,7 @@ class PowerWeight : public TupleWeight<W, n> {
   static const string &Type() {
     static string type;
     if (type.empty()) {
-      string power;
-      Int64ToStr(n, &power);
-      type = W::Type() + "_^" + power;
+      type = W::Type() + "_^" + std::to_string(n);
     }
     return type;
   }
index fe0acbe..e1106ae 100644 (file)
@@ -46,8 +46,9 @@ class ProductWeight : public PairWeight<W1, W2> {
   }
 
   static const string &Type() {
-    static const string type = W1::Type() + "_X_" + W2::Type();
-    return type;
+    static const string *const type =
+        new string(W1::Type() + "_X_" + W2::Type());
+    return *type;
   }
 
   static constexpr uint64 Properties() {
index 032ccfc..49daa03 100644 (file)
@@ -55,12 +55,13 @@ struct PruneOptions {
 
   PruneOptions(const Weight &weight_threshold, StateId state_threshold,
                ArcFilter filter, std::vector<Weight> *distance = nullptr,
-               float delta = kDelta)
+               float delta = kDelta, bool threshold_initial = false)
       : weight_threshold(std::move(weight_threshold)),
         state_threshold(state_threshold),
         filter(std::move(filter)),
         distance(distance),
-        delta(delta) {}
+        delta(delta),
+        threshold_initial(threshold_initial) {}
 
   // Pruning weight threshold.
   Weight weight_threshold;
@@ -73,6 +74,11 @@ struct PruneOptions {
   // Determines the degree of convergence required when computing shortest
   // distances.
   float delta;
+  // Determines if the shortest path weight is left (true) or right
+  // (false) multiplied by the threshold to get the limit for
+  // keeping a state or arc (matters if the semiring is not
+  // commutative).
+  bool threshold_initial;
 };
 
 // Pruning algorithm: this version modifies its input and it takes an options
@@ -81,8 +87,7 @@ struct PruneOptions {
 // weight of the shortest path Times() the provided weight threshold. When the
 // state threshold is not kNoStateId, the output FST is further restricted to
 // have no more than the number of states in opts.state_threshold. Weights must
-// be commutative and have the path property. The weight of any cycle needs to
-// be bounded; i.e.,
+// have the path property. The weight of any cycle needs to be bounded; i.e.,
 //
 //   Plus(weight, Weight::One()) == Weight::One()
 template <class Arc, class ArcFilter>
@@ -95,10 +100,9 @@ void Prune(MutableFst<Arc> *fst, const PruneOptions<Arc, ArcFilter> &opts) {
   // 2) We have a pleasant way to "deregister" this operation for non-path
   //    semirings so an informative error message is produced. The best
   //    solution will probably involve some kind of SFINAE magic.
-  if ((Weight::Properties() & (kPath | kCommutative)) !=
-      (kPath | kCommutative)) {
-    FSTERROR() << "Prune: Weight needs to have the path property and"
-               << " be commutative: " << Weight::Type();
+  if ((Weight::Properties() & kPath) != kPath) {
+    FSTERROR() << "Prune: Weight needs to have the path property: "
+               << Weight::Type();
     fst->SetProperties(kError, kError);
     return;
   }
@@ -123,9 +127,12 @@ void Prune(MutableFst<Arc> *fst, const PruneOptions<Arc, ArcFilter> &opts) {
   std::vector<StateId> dead;
   dead.push_back(fst->AddState());
   NaturalLess<Weight> less;
-  const auto limit = Times((*fdistance)[fst->Start()], opts.weight_threshold);
-  StateId num_visited = 0;
   auto s = fst->Start();
+  const auto limit = opts.threshold_initial ?
+      Times(opts.weight_threshold, (*fdistance)[s]) :
+      Times((*fdistance)[s], opts.weight_threshold);
+  StateId num_visited = 0;
+
   if (!less(limit, (*fdistance)[s])) {
     idistance[s] = Weight::One();
     enqueued[s] = heap.Insert(s);
@@ -173,13 +180,14 @@ void Prune(MutableFst<Arc> *fst, const PruneOptions<Arc, ArcFilter> &opts) {
   fst->DeleteStates(dead);
 }
 
-// Pruning algorithm: this version modifies its input and takes the pruning
-// threshold as an argument. It deletes states and arcs in the FST that do not
-// belong to a successful path whose weight is more than the weight of the
-// shortest path Times() the provided weight threshold. When the state threshold
-// is not kNoStateId, the output FST is further restricted to have no more than
-// the number of states in opts.state_threshold. Weights must be commutative and
-// have the path property. The weight of any cycle needs to be bounded; i.e.,
+// Pruning algorithm: this version modifies its input and takes the
+// pruning threshold as an argument. It deletes states and arcs in the
+// FST that do not belong to a successful path whose weight is more
+// than the weight of the shortest path Times() the provided weight
+// threshold. When the state threshold is not kNoStateId, the output
+// FST is further restricted to have no more than the number of states
+// in opts.state_threshold. Weights must have the path property. The
+// weight of any cycle needs to be bounded; i.e.,
 //
 //   Plus(weight, Weight::One()) == Weight::One()
 template <class Arc>
@@ -191,14 +199,15 @@ void Prune(MutableFst<Arc> *fst, typename Arc::Weight weight_threshold,
   Prune(fst, opts);
 }
 
-// Pruning algorithm: this version writes the pruned input FST to an output
-// MutableFst and it takes an options class as an argument. The output FST
-// contains states and arcs that belong to a successful path in the input FST
-// whose weight is more than the weight of the shortest path Times() the
-// provided weight threshold. When the state threshold is not kNoStateId, the
-// output FST is further restricted to have no more than the number of states in
-// opts.state_threshold. Weights must be commutative and have the path property.
-// The weight of any cycle needs to be bounded; i.e.,
+// Pruning algorithm: this version writes the pruned input FST to an
+// output MutableFst and it takes an options class as an argument. The
+// output FST contains states and arcs that belong to a successful
+// path in the input FST whose weight is more than the weight of the
+// shortest path Times() the provided weight threshold. When the state
+// threshold is not kNoStateId, the output FST is further restricted
+// to have no more than the number of states in
+// opts.state_threshold. Weights have the path property.  The weight
+// of any cycle needs to be bounded; i.e.,
 //
 //   Plus(weight, Weight::One()) == Weight::One()
 template <class Arc, class ArcFilter>
@@ -212,10 +221,9 @@ void Prune(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
   // 2) We have a pleasant way to "deregister" this operation for non-path
   //    semirings so an informative error message is produced. The best
   //    solution will probably involve some kind of SFINAE magic.
-  if ((Weight::Properties() & (kPath | kCommutative)) !=
-      (kPath | kCommutative)) {
-    FSTERROR() << "Prune: Weight needs to have the path property and"
-               << " be commutative: " << Weight::Type();
+  if ((Weight::Properties() & kPath) != kPath) {
+    FSTERROR() << "Prune: Weight needs to have the path property: "
+               << Weight::Type();
     ofst->SetProperties(kError, kError);
     return;
   }
@@ -242,9 +250,9 @@ void Prune(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
   std::vector<size_t> enqueued;
   std::vector<bool> visited;
   auto s = ifst.Start();
-  const auto limit = Times(s < fdistance->size() ?
-                           (*fdistance)[s] : Weight::Zero(),
-                           opts.weight_threshold);
+  const auto limit = opts.threshold_initial ?
+      Times(opts.weight_threshold, (*fdistance)[s]) :
+      Times((*fdistance)[s], opts.weight_threshold);
   while (copy.size() <= s) copy.push_back(kNoStateId);
   copy[s] = ofst->AddState();
   ofst->SetStart(copy[s]);
@@ -300,14 +308,15 @@ void Prune(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
   }
 }
 
-// Pruning algorithm: this version writes the pruned input FST to an output
-// MutableFst and simply takes the pruning threshold as an argument. The output
-// FST contains states and arcs that belong to a successful path in the input
-// FST whose weight is no more than the weight of the shortest path Times()
-// the provided weight threshold. When the state threshold is not kNoStateId,
-// the output FST is further restricted to have no more than the number of
-// states in opts.state_threshold. Weights must be commutative and have the
-// path property. The weight of any cycle needs to be bounded; i.e.,
+// Pruning algorithm: this version writes the pruned input FST to an
+// output MutableFst and simply takes the pruning threshold as an
+// argument. The output FST contains states and arcs that belong to a
+// successful path in the input FST whose weight is no more than the
+// weight of the shortest path Times() the provided weight
+// threshold. When the state threshold is not kNoStateId, the output
+// FST is further restricted to have no more than the number of states
+// in opts.state_threshold. Weights must have the path property. The
+// weight of any cycle needs to be bounded; i.e.,
 //
 // Plus(weight, Weight::One()) = Weight::One();
 template <class Arc>
index 13bb55d..d5e8985 100644 (file)
@@ -132,7 +132,7 @@ void Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint32 ptype,
       total_weight = GallicWeight(
           ptype & kPushRemoveCommonAffix
               ? total_weight.Value1()
-              : StringWeight<Label, GALLIC_STRING_TYPE(gtype)>::One(),
+              : StringWeight<Label, GallicStringType(gtype)>::One(),
           ptype & kPushRemoveTotalWeight ? total_weight.Value2()
                                          : Weight::One());
     }
index e5f3678..d8b8c02 100644 (file)
@@ -6,10 +6,6 @@
 #ifndef FST_LIB_RANDGEN_H_
 #define FST_LIB_RANDGEN_H_
 
-#include <cmath>
-#include <cstdlib>
-#include <ctime>
-#include <limits>
 #include <map>
 #include <random>
 
@@ -32,32 +28,44 @@ namespace fst {
 // selected. It is assumed these are not applied to any state which is neither
 // final nor has any arcs leaving it.
 
-// Randomly selects a transition using the uniform distribution.
+// Randomly selects a transition using the uniform distribution. This class is
+// not thread-safe.
 template <class Arc>
-struct UniformArcSelector {
+class UniformArcSelector {
+ public:
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  explicit UniformArcSelector(time_t seed = time(nullptr)) { srand(seed); }
+  // Constructs a selector with a non-deterministic seed.
+  UniformArcSelector() : rand_(std::random_device()()) {}
+  // Constructs a selector with a given seed.
+  explicit UniformArcSelector(uint64 seed) : rand_(seed) {}
 
   size_t operator()(const Fst<Arc> &fst, StateId s) const {
-    const double r = rand() / (RAND_MAX + 1.0);  // NOLINT
     const auto n = fst.NumArcs(s) + (fst.Final(s) != Weight::Zero());
-    return static_cast<size_t>(r * n);
+    return static_cast<size_t>(
+        std::uniform_int_distribution<>(0, n - 1)(rand_));
   }
+
+ private:
+  mutable std::mt19937_64 rand_;
 };
 
 // Randomly selects a transition w.r.t. the weights treated as negative log
 // probabilities after normalizing for the total weight leaving the state. Zero
 // transitions are disregarded. It assumed that Arc::Weight::Value() accesses
-// the floating point representation of the weight.
+// the floating point representation of the weight. This class is not
+// thread-safe.
 template <class Arc>
 class LogProbArcSelector {
  public:
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  explicit LogProbArcSelector(time_t seed = time(nullptr)) { srand(seed); }
+  // Constructs a selector with a non-deterministic seed.
+  LogProbArcSelector() : rand_(std::random_device()()) {}
+  // Constructs a selector with a given seed.
+  explicit LogProbArcSelector(uint64 seed) : rand_(seed) {}
 
   size_t operator()(const Fst<Arc> &fst, StateId s) const {
     // Finds total weight leaving state.
@@ -69,7 +77,7 @@ class LogProbArcSelector {
     }
     sum = Plus(sum, to_log_weight_(fst.Final(s)));
     const double threshold =
-        (exp(-sum.Value()) * (rand() / (RAND_MAX + 1.0)));  // NOLINT
+        std::uniform_real_distribution<>(0, exp(-sum.Value()))(rand_);
     auto p = Log64Weight::Zero();
     size_t n = 0;
     for (aiter.Reset(); !aiter.Done(); aiter.Next(), ++n) {
@@ -80,14 +88,15 @@ class LogProbArcSelector {
   }
 
  private:
+  mutable std::mt19937_64 rand_;
   WeightConvert<Weight, Log64Weight> to_log_weight_;
 };
 
 // Useful alias when using StdArc.
 using StdArcSelector = LogProbArcSelector<StdArc>;
 
-// Same as LogProbArcSelector but use CacheLogAccumulator to cache the
-// weight accumulation computations.
+// Same as LogProbArcSelector but use CacheLogAccumulator to cache the weight
+// accumulation computations. This class is not thread-safe.
 template <class Arc>
 class FastLogProbArcSelector : public LogProbArcSelector<Arc> {
  public:
@@ -96,8 +105,10 @@ class FastLogProbArcSelector : public LogProbArcSelector<Arc> {
 
   using LogProbArcSelector<Arc>::operator();
 
-  explicit FastLogProbArcSelector(time_t seed = time(nullptr))
-      : LogProbArcSelector<Arc>(seed), seed_(seed) {}
+  // Constructs a selector with a non-deterministic seed.
+  FastLogProbArcSelector() : seed_(std::random_device()()), rand_(seed_) {}
+  // Constructs a selector with a given seed.
+  explicit FastLogProbArcSelector(uint64 seed) : seed_(seed), rand_(seed_) {}
 
   size_t operator()(const Fst<Arc> &fst, StateId s,
                     CacheLogAccumulator<Arc> *accumulator) const {
@@ -107,16 +118,17 @@ class FastLogProbArcSelector : public LogProbArcSelector<Arc> {
     const double sum = to_log_weight_(accumulator->Sum(fst.Final(s), &aiter, 0,
                                                        fst.NumArcs(s)))
                            .Value();
-    const double r = -log(rand() / (RAND_MAX + 1.0));  // NOLINT
+    const double r = -log(std::uniform_real_distribution<>(0, 1)(rand_));
     Weight w = from_log_weight_(r + sum);
     aiter.Reset();
     return accumulator->LowerBound(w, &aiter);
   }
 
-  time_t Seed() const { return seed_; }
+  uint64 Seed() const { return seed_; }
 
  private:
-  const time_t seed_;
+  const uint64 seed_;
+  mutable std::mt19937_64 rand_;
   WeightConvert<Weight, Log64Weight> to_log_weight_;
   WeightConvert<Log64Weight, Weight> from_log_weight_;
 };
index 7e6b7fb..b9c6ae4 100644 (file)
@@ -7,15 +7,15 @@
 #define FST_SCRIPT_COMPILE_IMPL_H_
 
 #include <iostream>
-#include <sstream>
 #include <memory>
+#include <sstream>
 #include <string>
-#include <unordered_map>
 #include <vector>
 
 #include <fst/fst.h>
 #include <fst/util.h>
 #include <fst/vector-fst.h>
+#include <unordered_map>
 
 DECLARE_string(fst_field_separator);
 
index 2fe6846..66e2186 100644 (file)
@@ -125,9 +125,7 @@ class FstDrawer {
       EscapeChars(symbol, &nsymbol);
       PrintString(nsymbol);
     } else {
-      string idstr;
-      Int64ToStr(id, &idstr);
-      PrintString(idstr);
+      PrintString(std::to_string(id));
     }
   }
 
index f032bef..cce115f 100644 (file)
@@ -110,6 +110,7 @@ class AllFstOperationsRegisterer {
     REGISTER_FST_OPERATION(Equal, Arc, EqualArgs);
     REGISTER_FST_OPERATION(Equivalent, Arc, EquivalentArgs);
     REGISTER_FST_OPERATION(PrintFstInfo, Arc, InfoArgs);
+    REGISTER_FST_OPERATION(GetFstInfo, Arc, GetInfoArgs);
     REGISTER_FST_OPERATION(InitArcIteratorClass, Arc,
                            InitArcIteratorClassArgs);
     REGISTER_FST_OPERATION(InitEncodeMapperClass, Arc,
index f7df9da..e895649 100644 (file)
@@ -27,18 +27,16 @@ namespace fst {
 // WARNING: Stand-alone use of this class is not recommended, most code
 // should call directly the relevant library functions: Fst<Arc>::NumStates,
 // Fst<Arc>::NumArcs, TestProperties, etc.
-template <class Arc>
 class FstInfo {
  public:
-  using Label = typename Arc::Label;
-  using StateId = typename Arc::StateId;
-  using Weight = typename Arc::Weight;
+  FstInfo() {}
 
   // When info_type is "short" (or "auto" and not an ExpandedFst) then only
   // 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", string info_type = "auto",
-          bool verify = true)
+          const string &arc_filter_type = "any",
+          const string &info_type = "auto", bool verify = true)
       : fst_type_(fst.Type()),
         input_symbols_(fst.InputSymbols() ? fst.InputSymbols()->Name()
                                           : "none"),
@@ -64,7 +62,11 @@ class FstInfo {
         output_lookahead_(false),
         properties_(0),
         arc_filter_type_(arc_filter_type),
-        long_info_(true) {
+        long_info_(true),
+        arc_type_(Arc::Type()) {
+    using Label = typename Arc::Label;
+    using StateId = typename Arc::StateId;
+    using Weight = typename Arc::Weight;
     if (info_type == "long") {
       long_info_ = true;
     } else if (info_type == "short") {
@@ -165,7 +167,7 @@ class FstInfo {
 
   const string &FstType() const { return fst_type_; }
 
-  const string &ArcType() const { return Arc::Type(); }
+  const string &ArcType() const { return arc_type_; }
 
   const string &InputSymbols() const { return input_symbols_; }
 
@@ -197,7 +199,7 @@ class FstInfo {
     return output_lookahead_;
   }
 
-  StateId NumStates() const {
+  int64 NumStates() const {
     CheckLong();
     return nstates_;
   }
@@ -207,7 +209,7 @@ class FstInfo {
     return narcs_;
   }
 
-  StateId Start() const {
+  int64 Start() const {
     CheckLong();
     return start_;
   }
@@ -281,9 +283,9 @@ class FstInfo {
   string fst_type_;
   string input_symbols_;
   string output_symbols_;
-  StateId nstates_;
+  int64 nstates_;
   size_t narcs_;
-  StateId start_;
+  int64 start_;
   size_t nfinal_;
   size_t nepsilons_;
   size_t niepsilons_;
@@ -302,104 +304,10 @@ class FstInfo {
   uint64 properties_;
   string arc_filter_type_;
   bool long_info_;
+  string arc_type_;
 };
 
-template <class Arc>
-void PrintFstInfo(const FstInfo<Arc> &fstinfo, bool pipe = false) {
-  std::ostream &ostrm = pipe ? std::cerr : std::cout;
-  const auto old = ostrm.setf(std::ios::left);
-  ostrm.width(50);
-  ostrm << "fst type" << fstinfo.FstType() << std::endl;
-  ostrm.width(50);
-  ostrm << "arc type" << fstinfo.ArcType() << std::endl;
-  ostrm.width(50);
-  ostrm << "input symbol table" << fstinfo.InputSymbols() << std::endl;
-  ostrm.width(50);
-  ostrm << "output symbol table" << fstinfo.OutputSymbols() << std::endl;
-  if (!fstinfo.LongInfo()) {
-    ostrm.setf(old);
-    return;
-  }
-  ostrm.width(50);
-  ostrm << "# of states" << fstinfo.NumStates() << std::endl;
-  ostrm.width(50);
-  ostrm << "# of arcs" << fstinfo.NumArcs() << std::endl;
-  ostrm.width(50);
-  ostrm << "initial state" << fstinfo.Start() << std::endl;
-  ostrm.width(50);
-  ostrm << "# of final states" << fstinfo.NumFinal() << std::endl;
-  ostrm.width(50);
-  ostrm << "# of input/output epsilons" << fstinfo.NumEpsilons() << std::endl;
-  ostrm.width(50);
-  ostrm << "# of input epsilons" << fstinfo.NumInputEpsilons() << std::endl;
-  ostrm.width(50);
-  ostrm << "# of output epsilons" << fstinfo.NumOutputEpsilons() << std::endl;
-  ostrm.width(50);
-  ostrm << "input label multiplicity" << fstinfo.InputLabelMultiplicity()
-        << std::endl;
-  ostrm.width(50);
-  ostrm << "output label multiplicity" << fstinfo.OutputLabelMultiplicity()
-        << std::endl;
-  ostrm.width(50);
-  string arc_type = "";
-  if (fstinfo.ArcFilterType() == "epsilon")
-    arc_type = "epsilon ";
-  else if (fstinfo.ArcFilterType() == "iepsilon")
-    arc_type = "input-epsilon ";
-  else if (fstinfo.ArcFilterType() == "oepsilon")
-    arc_type = "output-epsilon ";
-  const auto accessible_label = "# of " + arc_type + "accessible states";
-  ostrm.width(50);
-  ostrm << accessible_label << fstinfo.NumAccessible() << std::endl;
-  const auto coaccessible_label = "# of " + arc_type + "coaccessible states";
-  ostrm.width(50);
-  ostrm << coaccessible_label << fstinfo.NumCoAccessible() << std::endl;
-  const auto connected_label = "# of " + arc_type + "connected states";
-  ostrm.width(50);
-  ostrm << connected_label << fstinfo.NumConnected() << std::endl;
-  const auto numcc_label = "# of " + arc_type + "connected components";
-  ostrm.width(50);
-  ostrm << numcc_label << fstinfo.NumCc() << std::endl;
-  const auto numscc_label = "# of " + arc_type + "strongly conn components";
-  ostrm.width(50);
-  ostrm << numscc_label << fstinfo.NumScc() << std::endl;
-  ostrm.width(50);
-  ostrm << "input matcher"
-        << (fstinfo.InputMatchType() == MATCH_INPUT
-                ? 'y'
-                : fstinfo.InputMatchType() == MATCH_NONE ? 'n' : '?')
-        << std::endl;
-  ostrm.width(50);
-  ostrm << "output matcher"
-        << (fstinfo.OutputMatchType() == MATCH_OUTPUT
-                ? 'y'
-                : fstinfo.OutputMatchType() == MATCH_NONE ? 'n' : '?')
-        << std::endl;
-  ostrm.width(50);
-  ostrm << "input lookahead" << (fstinfo.InputLookAhead() ? 'y' : 'n')
-        << std::endl;
-  ostrm.width(50);
-  ostrm << "output lookahead" << (fstinfo.OutputLookAhead() ? 'y' : 'n')
-        << std::endl;
-  uint64 prop = 1;
-  for (auto i = 0; i < 64; ++i, prop <<= 1) {
-    if (prop & kBinaryProperties) {
-      char value = 'n';
-      if (fstinfo.Properties() & prop) value = 'y';
-      ostrm.width(50);
-      ostrm << PropertyNames[i] << value << std::endl;
-    } else if (prop & kPosTrinaryProperties) {
-      char value = '?';
-      if (fstinfo.Properties() & prop)
-        value = 'y';
-      else if (fstinfo.Properties() & prop << 1)
-        value = 'n';
-      ostrm.width(50);
-      ostrm << PropertyNames[i] << value << std::endl;
-    }
-  }
-  ostrm.setf(old);
-}
+void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe = false);
 
 }  // namespace fst
 
index 091e34a..5480da7 100644 (file)
@@ -17,8 +17,8 @@ using InfoArgs = args::Package<const FstClass &, bool, const string &,
 template <class Arc>
 void PrintFstInfo(InfoArgs *args) {
   const Fst<Arc> &fst = *(args->arg1.GetFst<Arc>());
-  FstInfo<Arc> fstinfo(fst, args->arg2, args->arg3, args->arg4, args->arg5);
-  PrintFstInfo(fstinfo, args->arg6);
+  FstInfo fstinfo(fst, args->arg2, args->arg3, args->arg4, args->arg5);
+  PrintFstInfoImpl(fstinfo, args->arg6);
   if (args->arg6) fst.Write("");
 }
 
@@ -26,6 +26,19 @@ void PrintFstInfo(const FstClass &f, bool test_properties,
                   const string &arc_filter, const string &info_type, bool pipe,
                   bool verify);
 
+using GetInfoArgs = args::Package<const FstClass &, bool, const string &,
+                                  const string &, bool, FstInfo *>;
+
+template <class Arc>
+void GetFstInfo(GetInfoArgs *args) {
+  const Fst<Arc> &fst = *(args->arg1.GetFst<Arc>());
+  *(args->arg6) = FstInfo(fst, args->arg2, args->arg3, args->arg4, args->arg5);
+}
+
+void GetFstInfo(const FstClass &f, bool test_properties,
+                const string &arc_filter, const string &info_type, bool verify,
+                FstInfo *info);
+
 }  // namespace script
 }  // namespace fst
 
index e6ec3a9..1345ab4 100644 (file)
@@ -54,8 +54,9 @@ class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
   }
 
   static const string &Type() {
-    static const string type = "signed_log_" + X1::Type() + "_" + X2::Type();
-    return type;
+    static const string *const type =
+        new string("signed_log_" + X1::Type() + "_" + X2::Type());
+    return *type;
   }
 
   SignedLogWeightTpl Quantize(float delta = kDelta) const {
@@ -208,8 +209,8 @@ using SignedLog64Weight = SignedLogWeightTpl<double>;
 template <class W1, class W2>
 bool SignedLogConvertCheck(W1 weight) {
   if (weight.Value1().Value() < 0.0) {
-    FSTERROR() << "WeightConvert: Can't convert weight from " << W1::Type()
-               << " to " << W2::Type();
+    FSTERROR() << "WeightConvert: Can't convert weight " << weight
+               << " from " << W1::Type() << " to " << W2::Type();
     return false;
   }
   return true;
index 813720e..1b6f83c 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef FST_LIB_SPARSE_POWER_WEIGHT_H_
 #define FST_LIB_SPARSE_POWER_WEIGHT_H_
 
+#include <climits>
 #include <string>
 
 #include <fst/sparse-tuple-weight.h>
@@ -103,9 +104,7 @@ class SparsePowerWeight : public SparseTupleWeight<W, K> {
     if (type.empty()) {
       type = W::Type() + "_^n";
       if (sizeof(K) != sizeof(uint32)) {
-        string size;
-        Int64ToStr(8 * sizeof(K), &size);
-        type += "_" + size;
+        type += "_" + std::to_string(CHAR_BIT * sizeof(K));
       }
     }
     return type;
index feb97a1..0cab323 100644 (file)
@@ -30,67 +30,59 @@ constexpr char kStringSeparator = '_';  // Label separator in strings.
 // string semirings.
 enum StringType { STRING_LEFT = 0, STRING_RIGHT = 1, STRING_RESTRICT = 2 };
 
-#define REVERSE_STRING_TYPE(S)       \
-  ((S) == STRING_LEFT ? STRING_RIGHT \
-                      : ((S) == STRING_RIGHT ? STRING_LEFT : STRING_RESTRICT))
-
-template <typename Label, StringType S = STRING_LEFT>
-class StringWeight;
+constexpr StringType ReverseStringType(StringType s) {
+  return s == STRING_LEFT ? STRING_RIGHT
+                          : (s == STRING_RIGHT ? STRING_LEFT : STRING_RESTRICT);
+}
 
-template <typename Label, StringType S = STRING_LEFT>
+template <class>
 class StringWeightIterator;
-
-template <typename Label, StringType S = STRING_LEFT>
+template <class>
 class StringWeightReverseIterator;
 
-template <typename Label, StringType S>
-bool operator==(const StringWeight<Label, S> &, const StringWeight<Label, S> &);
-
 // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon)
-template <typename Label, StringType S>
+template <typename Label_, StringType S = STRING_LEFT>
 class StringWeight {
  public:
-  using ReverseWeight = StringWeight<Label, REVERSE_STRING_TYPE(S)>;
+  using Label = Label_;
+  using Self = StringWeight<Label, S>;
+  using ReverseWeight = StringWeight<Label, ReverseStringType(S)>;
+  using Iterator = StringWeightIterator<Self>;
+  using ReverseIterator = StringWeightReverseIterator<Self>;
 
-  friend class StringWeightIterator<Label, S>;
-  friend class StringWeightReverseIterator<Label, S>;
-  friend bool operator==
-      <>(const StringWeight<Label, S> &, const StringWeight<Label, S> &);
+  friend class StringWeightIterator<Self>;
+  friend class StringWeightReverseIterator<Self>;
 
-  StringWeight() { Init(); }
+  StringWeight() {}
 
   template <typename Iterator>
   StringWeight(const Iterator &begin, const Iterator &end) {
-    Init();
     for (auto iter = begin; iter != end; ++iter) PushBack(*iter);
   }
 
-  explicit StringWeight(Label label) {
-    Init();
-    PushBack(label);
-  }
+  explicit StringWeight(Label label) { PushBack(label); }
 
-  static const StringWeight<Label, S> &Zero() {
-    static const StringWeight<Label, S> zero(kStringInfinity);
-    return zero;
+  static const Self &Zero() {
+    static const Self *const zero = new Self(Label(kStringInfinity));
+    return *zero;
   }
 
-  static const StringWeight<Label, S> &One() {
-    static const StringWeight<Label, S> one;
-    return one;
+  static const Self &One() {
+    static const Self *const one = new Self();
+    return *one;
   }
 
-  static const StringWeight<Label, S> &NoWeight() {
-    static const StringWeight<Label, S> no_weight(kStringBad);
-    return no_weight;
+  static const Self &NoWeight() {
+    static const Self *const no_weight = new Self(Label(kStringBad));
+    return *no_weight;
   }
 
   static const string &Type() {
-    static const string type =
+    static const string *const type = new string(
         S == STRING_LEFT
             ? "left_string"
-            : (S == STRING_RIGHT ? "right_string" : "restricted_string");
-    return type;
+            : (S == STRING_RIGHT ? "right_string" : "restricted_string"));
+    return *type;
   }
 
   bool Member() const;
@@ -101,34 +93,23 @@ class StringWeight {
 
   size_t Hash() const;
 
-  StringWeight<Label, S> Quantize(float delta = kDelta) const { return *this; }
+  Self Quantize(float delta = kDelta) const { return *this; }
 
   ReverseWeight Reverse() const;
 
-  // TODO(kbg): Make this constexpr once C++14 support for conditionals in
-  // constexpr functions hits. As is, it can only be done very awkwardly with
-  // SFINAE enable-if magic.
-  static uint64 Properties() {
-    if (S == STRING_LEFT) {
-      static constexpr auto props = kLeftSemiring | kIdempotent;
-      return props;
-    } else if (S == STRING_RIGHT) {
-      static constexpr auto props = kRightSemiring | kIdempotent;
-      return props;
-    } else {
-      static constexpr auto props =
-          kLeftSemiring | kRightSemiring | kIdempotent;
-      return props;
-    }
+  static constexpr uint64 Properties() {
+    return kIdempotent |
+           (S == STRING_LEFT ? kLeftSemiring
+                             : (S == STRING_RIGHT
+                                    ? kRightSemiring
+                                    : /* S == STRING_RESTRICT */ kLeftSemiring |
+                                          kRightSemiring));
   }
 
   // These operations combined with the StringWeightIterator and
   // StringWeightReverseIterator provide the access and mutation of the string
   // internal elements.
 
-  // Common initializer among constructors.
-  void Init() { first_ = 0; }
-
   // Clear existing StringWeight.
   void Clear() {
     first_ = 0;
@@ -151,15 +132,18 @@ class StringWeight {
   }
 
  private:
-  Label first_;            // Rirst label in string (0 if empty).
+  Label first_ = 0;        // First label in string (0 if empty).
   std::list<Label> rest_;  // Remaining labels in string.
 };
 
 // Traverses string in forward direction.
-template <typename Label, StringType S>
+template <class StringWeight_>
 class StringWeightIterator {
  public:
-  explicit StringWeightIterator(const StringWeight<Label, S> &w)
+  using Weight = StringWeight_;
+  using Label = typename Weight::Label;
+
+  explicit StringWeightIterator(const Weight &w)
       : first_(w.first_), rest_(w.rest_), init_(true), iter_(rest_.begin()) {}
 
   bool Done() const {
@@ -187,19 +171,22 @@ class StringWeightIterator {
 
  private:
   const Label &first_;
-  const std::list<Label> &rest_;
+  const decltype(Weight::rest_) &rest_;
   bool init_;  // In the initialized state?
-  typename std::list<Label>::const_iterator iter_;
+  typename decltype(Weight::rest_)::const_iterator iter_;
 };
 
 // Traverses string in backward direction.
-template <typename Label, StringType S>
+template <class StringWeight_>
 class StringWeightReverseIterator {
  public:
-  explicit StringWeightReverseIterator(const StringWeight<Label, S> &w)
+  using Weight = StringWeight_;
+  using Label = typename Weight::Label;
+
+  explicit StringWeightReverseIterator(const Weight &w)
       : first_(w.first_),
         rest_(w.rest_),
-        fin_(first_ == 0),
+        fin_(first_ == Label()),
         iter_(rest_.rbegin()) {}
 
   bool Done() const { return fin_; }
@@ -221,9 +208,9 @@ class StringWeightReverseIterator {
 
  private:
   const Label &first_;
-  const std::list<Label> &rest_;
+  const decltype(Weight::rest_) &rest_;
   bool fin_;  // In the final state?
-  typename std::list<Label>::const_reverse_iterator iter_;
+  typename decltype(Weight::rest_)::const_reverse_iterator iter_;
 };
 
 // StringWeight member functions follow that require
@@ -246,7 +233,7 @@ template <typename Label, StringType S>
 inline std::ostream &StringWeight<Label, S>::Write(std::ostream &strm) const {
   const int32 size = Size();
   WriteType(strm, size);
-  for (StringWeightIterator<Label, S> iter(*this); !iter.Done(); iter.Next()) {
+  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
     WriteType(strm, iter.Value());
   }
   return strm;
@@ -254,15 +241,15 @@ inline std::ostream &StringWeight<Label, S>::Write(std::ostream &strm) const {
 
 template <typename Label, StringType S>
 inline bool StringWeight<Label, S>::Member() const {
-  StringWeightIterator<Label, S> iter(*this);
-  return iter.Value() != kStringBad;
+  Iterator iter(*this);
+  return iter.Value() != Label(kStringBad);
 }
 
 template <typename Label, StringType S>
 inline typename StringWeight<Label, S>::ReverseWeight
 StringWeight<Label, S>::Reverse() const {
   ReverseWeight rweight;
-  for (StringWeightIterator<Label, S> iter(*this); !iter.Done(); iter.Next()) {
+  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
     rweight.PushFront(iter.Value());
   }
   return rweight;
@@ -271,7 +258,7 @@ StringWeight<Label, S>::Reverse() const {
 template <typename Label, StringType S>
 inline size_t StringWeight<Label, S>::Hash() const {
   size_t h = 0;
-  for (StringWeightIterator<Label, S> iter(*this); !iter.Done(); iter.Next()) {
+  for (Iterator iter(*this); !iter.Done(); iter.Next()) {
     h ^= h << 1 ^ iter.Value();
   }
   return h;
@@ -281,9 +268,9 @@ template <typename Label, StringType S>
 inline bool operator==(const StringWeight<Label, S> &w1,
                        const StringWeight<Label, S> &w2) {
   if (w1.Size() != w2.Size()) return false;
-  using WeightIterator = StringWeightIterator<Label, S>;
-  WeightIterator iter1(w1);
-  WeightIterator iter2(w2);
+  using Iterator = typename StringWeight<Label, S>::Iterator;
+  Iterator iter1(w1);
+  Iterator iter2(w2);
   for (; !iter1.Done(); iter1.Next(), iter2.Next()) {
     if (iter1.Value() != iter2.Value()) return false;
   }
@@ -306,12 +293,12 @@ inline bool ApproxEqual(const StringWeight<Label, S> &w1,
 template <typename Label, StringType S>
 inline std::ostream &operator<<(std::ostream &strm,
                                 const StringWeight<Label, S> &weight) {
-  StringWeightIterator<Label, S> iter(weight);
+  typename StringWeight<Label, S>::Iterator iter(weight);
   if (iter.Done()) {
     return strm << "Epsilon";
-  } else if (iter.Value() == kStringInfinity) {
+  } else if (iter.Value() == Label(kStringInfinity)) {
     return strm << "Infinity";
-  } else if (iter.Value() == kStringBad) {
+  } else if (iter.Value() == Label(kStringBad)) {
     return strm << "BadString";
   } else {
     for (size_t i = 0; !iter.Done(); ++i, iter.Next()) {
@@ -327,10 +314,11 @@ inline std::istream &operator>>(std::istream &strm,
                                 StringWeight<Label, S> &weight) {
   string str;
   strm >> str;
+  using Weight = StringWeight<Label, S>;
   if (str == "Infinity") {
-    weight = StringWeight<Label, S>::Zero();
+    weight = Weight::Zero();
   } else if (str == "Epsilon") {
-    weight = StringWeight<Label, S>::One();
+    weight = Weight::One();
   } else {
     weight.Clear();
     char *p = nullptr;
@@ -375,9 +363,8 @@ inline StringWeight<Label, STRING_LEFT> Plus(
   if (w1 == Weight::Zero()) return w2;
   if (w2 == Weight::Zero()) return w1;
   Weight sum;
-  using WeightIterator = StringWeightIterator<Label, STRING_LEFT>;
-  WeightIterator iter1(w1);
-  WeightIterator iter2(w2);
+  typename Weight::Iterator iter1(w1);
+  typename Weight::Iterator iter2(w2);
   for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
        iter1.Next(), iter2.Next()) {
     sum.PushBack(iter1.Value());
@@ -395,10 +382,8 @@ inline StringWeight<Label, STRING_RIGHT> Plus(
   if (w1 == Weight::Zero()) return w2;
   if (w2 == Weight::Zero()) return w1;
   Weight sum;
-  using WeightReverseIterator =
-      StringWeightReverseIterator<Label, STRING_RIGHT>;
-  WeightReverseIterator iter1(w1);
-  WeightReverseIterator iter2(w2);
+  typename Weight::ReverseIterator iter1(w1);
+  typename Weight::ReverseIterator iter2(w2);
   for (; !iter1.Done() && !iter2.Done() && iter1.Value() == iter2.Value();
        iter1.Next(), iter2.Next()) {
     sum.PushFront(iter1.Value());
@@ -413,7 +398,7 @@ inline StringWeight<Label, S> Times(const StringWeight<Label, S> &w1,
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
   if (w1 == Weight::Zero() || w2 == Weight::Zero()) return Weight::Zero();
   Weight product(w1);
-  for (StringWeightIterator<Label, S> iter(w2); !iter.Done(); iter.Next()) {
+  for (typename Weight::Iterator iter(w2); !iter.Done(); iter.Next()) {
     product.PushBack(iter.Value());
   }
   return product;
@@ -426,12 +411,12 @@ inline StringWeight<Label, S> DivideLeft(const StringWeight<Label, S> &w1,
   using Weight = StringWeight<Label, S>;
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
   if (w2 == Weight::Zero()) {
-    return Weight(kStringBad);
+    return Weight(Label(kStringBad));
   } else if (w1 == Weight::Zero()) {
     return Weight::Zero();
   }
   Weight result;
-  StringWeightIterator<Label, S> iter(w1);
+  typename Weight::Iterator iter(w1);
   size_t i = 0;
   for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
   }
@@ -446,12 +431,12 @@ inline StringWeight<Label, S> DivideRight(const StringWeight<Label, S> &w1,
   using Weight = StringWeight<Label, S>;
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
   if (w2 == Weight::Zero()) {
-    return Weight(kStringBad);
+    return Weight(Label(kStringBad));
   } else if (w1 == Weight::Zero()) {
     return Weight::Zero();
   }
   Weight result;
-  StringWeightReverseIterator<Label, S> iter(w1);
+  typename Weight::ReverseIterator iter(w1);
   size_t i = 0;
   for (; !iter.Done() && i < w2.Size(); iter.Next(), ++i) {
   }
@@ -514,7 +499,8 @@ class WeightGenerate<StringWeight<Label, S>> {
   explicit WeightGenerate(bool allow_zero = true,
                           size_t alphabet_size = kNumRandomWeights,
                           size_t max_string_length = kNumRandomWeights)
-      : allow_zero_(allow_zero), alphabet_size_(alphabet_size),
+      : allow_zero_(allow_zero),
+        alphabet_size_(alphabet_size),
         max_string_length_(max_string_length) {}
 
   Weight operator()() const {
@@ -549,26 +535,29 @@ enum GallicType {
   GALLIC = 4
 };
 
-#define GALLIC_STRING_TYPE(G)                                             \
-  ((G) == GALLIC_LEFT ? STRING_LEFT : ((G) == GALLIC_RIGHT ? STRING_RIGHT \
-                                                           : STRING_RESTRICT))
+constexpr StringType GallicStringType(GallicType g) {
+  return g == GALLIC_LEFT
+             ? STRING_LEFT
+             : (g == GALLIC_RIGHT ? STRING_RIGHT : STRING_RESTRICT);
+}
 
-#define REVERSE_GALLIC_TYPE(G)          \
-  ((G) == GALLIC_LEFT                   \
-       ? GALLIC_RIGHT                   \
-       : ((G) == GALLIC_RIGHT           \
-              ? GALLIC_LEFT             \
-              : ((G) == GALLIC_RESTRICT \
-                     ? GALLIC_RESTRICT  \
-                     : ((G) == GALLIC_MIN ? GALLIC_MIN : GALLIC))))
+constexpr GallicType ReverseGallicType(GallicType g) {
+  return g == GALLIC_LEFT
+             ? GALLIC_RIGHT
+             : (g == GALLIC_RIGHT
+                    ? GALLIC_LEFT
+                    : (g == GALLIC_RESTRICT
+                           ? GALLIC_RESTRICT
+                           : (g == GALLIC_MIN ? GALLIC_MIN : GALLIC)));
+}
 
 // Product of string weight and an arbitraryy weight.
 template <class Label, class W, GallicType G = GALLIC_LEFT>
 struct GallicWeight
-    : public ProductWeight<StringWeight<Label, GALLIC_STRING_TYPE(G)>, W> {
+    : public ProductWeight<StringWeight<Label, GallicStringType(G)>, W> {
   using ReverseWeight =
-      GallicWeight<Label, typename W::ReverseWeight, REVERSE_GALLIC_TYPE(G)>;
-  using SW = StringWeight<Label, GALLIC_STRING_TYPE(G)>;
+      GallicWeight<Label, typename W::ReverseWeight, ReverseGallicType(G)>;
+  using SW = StringWeight<Label, GallicStringType(G)>;
 
   using ProductWeight<SW, W>::Properties;
 
@@ -598,15 +587,15 @@ struct GallicWeight
   }
 
   static const string &Type() {
-    static const string type =
+    static const string *const type = new string(
         G == GALLIC_LEFT
             ? "left_gallic"
             : (G == GALLIC_RIGHT
                    ? "right_gallic"
                    : (G == GALLIC_RESTRICT
                           ? "restricted_gallic"
-                          : (G == GALLIC_MIN ? "min_gallic" : "gallic")));
-    return type;
+                          : (G == GALLIC_MIN ? "min_gallic" : "gallic"))));
+    return *type;
   }
 
   GallicWeight Quantize(float delta = kDelta) const {
@@ -655,11 +644,11 @@ inline GallicWeight<Label, W, G> Divide(const GallicWeight<Label, W, G> &w,
 template <class Label, class W, GallicType G>
 class WeightGenerate<GallicWeight<Label, W, G>>
     : public WeightGenerate<
-          ProductWeight<StringWeight<Label, GALLIC_STRING_TYPE(G)>, W>> {
+          ProductWeight<StringWeight<Label, GallicStringType(G)>, W>> {
  public:
   using Weight = GallicWeight<Label, W, G>;
   using Generate = WeightGenerate<
-      ProductWeight<StringWeight<Label, GALLIC_STRING_TYPE(G)>, W>>;
+      ProductWeight<StringWeight<Label, GallicStringType(G)>, W>>;
 
   explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
 
@@ -674,8 +663,8 @@ template <class Label, class W>
 struct GallicUnionWeightOptions {
   using ReverseOptions = GallicUnionWeightOptions<Label, W>;
   using GW = GallicWeight<Label, W, GALLIC_RESTRICT>;
-  using SW = StringWeight<Label, GALLIC_STRING_TYPE(GALLIC_RESTRICT)>;
-  using SI = StringWeightIterator<Label, GALLIC_STRING_TYPE(GALLIC_RESTRICT)>;
+  using SW = StringWeight<Label, GallicStringType(GALLIC_RESTRICT)>;
+  using SI = StringWeightIterator<SW>;
 
   // Military order.
   struct Compare {
@@ -712,8 +701,8 @@ struct GallicWeight<Label, W, GALLIC>
     : public UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
                          GallicUnionWeightOptions<Label, W>> {
   using GW = GallicWeight<Label, W, GALLIC_RESTRICT>;
-  using SW = StringWeight<Label, GALLIC_STRING_TYPE(GALLIC_RESTRICT)>;
-  using SI = StringWeightIterator<Label, GALLIC_STRING_TYPE(GALLIC_RESTRICT)>;
+  using SW = StringWeight<Label, GallicStringType(GALLIC_RESTRICT)>;
+  using SI = StringWeightIterator<SW>;
   using UW = UnionWeight<GW, GallicUnionWeightOptions<Label, W>>;
   using UI = UnionWeightIterator<GW, GallicUnionWeightOptions<Label, W>>;
   using ReverseWeight = GallicWeight<Label, W, GALLIC>;
@@ -751,8 +740,8 @@ struct GallicWeight<Label, W, GALLIC>
   }
 
   static const string &Type() {
-    static const string type = "gallic";
-    return type;
+    static const string *const type = new string("gallic");
+    return *type;
   }
 
   GallicWeight<Label, W, GALLIC> Quantize(float delta = kDelta) const {
index 02ee804..3b1a585 100644 (file)
@@ -243,7 +243,7 @@ class SymbolTable {
   // Reads a text representation of the symbol table.
   static SymbolTable *ReadText(const string &filename,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions()) {
-    std::ifstream strm(filename.c_str(), std::ios_base::in);
+    std::ifstream strm(filename, std::ios_base::in);
     if (!strm.good()) {
       LOG(ERROR) << "SymbolTable::ReadText: Can't open file " << filename;
       return nullptr;
@@ -269,7 +269,7 @@ class SymbolTable {
 
   // Reads a binary dump of the symbol table.
   static SymbolTable *Read(const string& filename) {
-    std::ifstream strm(filename.c_str(),
+    std::ifstream strm(filename,
                             std::ios_base::in | std::ios_base::binary);
     if (!strm.good()) {
       LOG(ERROR) << "SymbolTable::Read: Can't open file " << filename;
@@ -329,7 +329,7 @@ class SymbolTable {
   virtual bool Write(std::ostream &strm) const { return impl_->Write(strm); }
 
   bool Write(const string &filename) const {
-    std::ofstream strm(filename.c_str(),
+    std::ofstream strm(filename,
                              std::ios_base::out | std::ios_base::binary);
     if (!strm.good()) {
       LOG(ERROR) << "SymbolTable::Write: Can't open file " << filename;
index 769304c..97144ea 100644 (file)
@@ -105,8 +105,8 @@ class UnionWeight {
   }
 
   static const string &Type() {
-    static const string type = W::Type() + "_union";
-    return type;
+    static const string *const type = new string(W::Type() + "_union");
+    return *type;
   }
 
   static constexpr uint64 Properties() {
index e0b82a5..cfd7912 100644 (file)
@@ -252,8 +252,6 @@ Weight StrToWeight(const string &s, const string &src, size_t nline) {
   return w;
 }
 
-void Int64ToStr(int64 n, string *s);
-
 template <typename Weight>
 void WeightToStr(Weight w, string *s) {
   std::ostringstream strm;
@@ -271,7 +269,7 @@ void SplitToVector(char *line, const char *delim, std::vector<char *> *vec,
 template <typename I>
 bool ReadIntPairs(const string &filename, std::vector<std::pair<I, I>> *pairs,
                   bool allow_negative = false) {
-  std::ifstream strm(filename.c_str(), std::ios_base::in);
+  std::ifstream strm(filename, std::ios_base::in);
   if (!strm) {
     LOG(ERROR) << "ReadIntPairs: Can't open file: " << filename;
     return false;
index dc5083c..d8e6ca5 100644 (file)
@@ -7,7 +7,9 @@
 #define FST_LIB_VECTOR_FST_H_
 
 #include <string>
+#include <utility>
 #include <vector>
+
 #include <fst/log.h>
 
 #include <fst/fst-decl.h>  // For optional argument declarations
@@ -68,7 +70,7 @@ class VectorState {
 
   void ReserveArcs(size_t n) { arcs_.reserve(n); }
 
-  void SetFinal(Weight weight) { final_ = weight; }
+  void SetFinal(Weight weight) { final_ = std::move(weight); }
 
   void SetNumInputEpsilons(size_t n) { niepsilons_ = n; }
 
@@ -161,7 +163,7 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
   void SetStart(StateId state) { start_ = state; }
 
   void SetFinal(StateId state, Weight weight) {
-    states_[state]->SetFinal(weight);
+    states_[state]->SetFinal(std::move(weight));
   }
 
   StateId AddState() {
@@ -301,7 +303,7 @@ class VectorFstImpl : public VectorFstBaseImpl<S> {
 
   void SetFinal(StateId state, Weight weight) {
     const auto old_weight = BaseImpl::Final(state);
-    BaseImpl::SetFinal(state, weight);
+    BaseImpl::SetFinal(state, std::move(weight));
     SetProperties(SetFinalProperties(Properties(), old_weight, weight));
   }
 
@@ -690,7 +692,7 @@ class MutableArcIterator<VectorFst<Arc, State>>
                     kNoOEpsilons | kWeighted | kUnweighted;
   }
 
-  constexpr uint32 Flags() const final { return kArcValueFlags; }
+  uint32 Flags() const final { return kArcValueFlags; }
 
   void SetFlags(uint32, uint32) final {}
 
index e5d1ec9..bc39db3 100644 (file)
@@ -10,6 +10,7 @@
 #include <cmath>
 #include <iostream>
 #include <sstream>
+#include <utility>
 
 #include <fst/compat.h>
 #include <fst/log.h>
@@ -219,18 +220,53 @@ struct WeightGenerate {
   }
 };
 
+namespace internal {
+
+class CompositeWeightIO {
+ public:
+  CompositeWeightIO();
+  CompositeWeightIO(char separator, std::pair<char, char> parentheses);
+
+  std::pair<char, char> parentheses() const {
+    return {open_paren_, close_paren_};
+  }
+  char separator() const { return separator_; }
+
+  bool error() const { return error_; }
+
+ protected:
+  const char separator_;
+  const char open_paren_;
+  const char close_paren_;
+
+ private:
+  bool error_;
+};
+
+}  // namespace internal
+
 // Helper class for writing textual composite weights.
-class CompositeWeightWriter {
+class CompositeWeightWriter : public internal::CompositeWeightIO {
  public:
+  // Uses configuration from flags (FLAGS_fst_weight_separator,
+  // FLAGS_fst_weight_parentheses).
   explicit CompositeWeightWriter(std::ostream &ostrm);
 
+  // parentheses defines the opening and closing parenthesis characters.
+  // Set parentheses = {0, 0} to disable writing parenthesis.
+  CompositeWeightWriter(std::ostream &ostrm, char separator,
+                        std::pair<char, char> parentheses);
+
+  CompositeWeightWriter(const CompositeWeightWriter &) = delete;
+  CompositeWeightWriter &operator=(const CompositeWeightWriter &) = delete;
+
   // Writes open parenthesis to a stream if option selected.
   void WriteBegin();
 
   // Writes element to a stream.
   template <class T>
   void WriteElement(const T &comp) {
-    if (i_++ > 0) ostrm_ << FLAGS_fst_weight_separator[0];
+    if (i_++ > 0) ostrm_ << separator_;
     ostrm_ << comp;
   }
 
@@ -239,19 +275,27 @@ class CompositeWeightWriter {
 
  private:
   std::ostream &ostrm_;
-  int i_;  // Element position.
-  CompositeWeightWriter(const CompositeWeightWriter &) = delete;
-  CompositeWeightWriter &operator=(const CompositeWeightWriter &) = delete;
+  int i_ = 0;  // Element position.
 };
 
 // Helper class for reading textual composite weights. Elements are separated by
-// FLAGS_fst_weight_separator. There must be at least one element per textual
-// representation.  FLAGS_fst_weight_parentheses should be set if the composite
+// a separator character. There must be at least one element per textual
+// representation.  Parentheses characters should be set if the composite
 // weights themselves contain composite weights to ensure proper parsing.
-class CompositeWeightReader {
+class CompositeWeightReader : public internal::CompositeWeightIO {
  public:
+  // Uses configuration from flags (FLAGS_fst_weight_separator,
+  // FLAGS_fst_weight_parentheses).
   explicit CompositeWeightReader(std::istream &istrm);
 
+  // parentheses defines the opening and closing parenthesis characters.
+  // Set parentheses = {0, 0} to disable reading parenthesis.
+  CompositeWeightReader(std::istream &istrm, char separator,
+                        std::pair<char, char> parentheses);
+
+  CompositeWeightReader(const CompositeWeightReader &) = delete;
+  CompositeWeightReader &operator=(const CompositeWeightReader &) = delete;
+
   // Reads open parenthesis from a stream if option selected.
   void ReadBegin();
 
@@ -266,32 +310,26 @@ class CompositeWeightReader {
 
  private:
   std::istream &istrm_;  // Input stream.
-  int c_;                // Last character read, or EOF.
-  char separator_;
-  bool has_parens_;
-  int depth_;  // Weight parentheses depth.
-  char open_paren_;
-  char close_paren_;
-
-  CompositeWeightReader(const CompositeWeightReader &) = delete;
-  CompositeWeightReader &operator=(const CompositeWeightReader &) = delete;
+  int c_ = 0;            // Last character read, or EOF.
+  int depth_ = 0;        // Weight parentheses depth.
 };
 
 template <class T>
 inline bool CompositeWeightReader::ReadElement(T *comp, bool last) {
   string s;
-  while ((c_ != EOF) && !std::isspace(c_) &&
+  const bool has_parens = open_paren_ != 0;
+  while ((c_ != std::istream::traits_type::eof()) && !std::isspace(c_) &&
          (c_ != separator_ || depth_ > 1 || last) &&
          (c_ != close_paren_ || depth_ != 1)) {
     s += c_;
     // If parentheses encountered before separator, they must be matched.
-    if (has_parens_ && c_ == open_paren_) {
+    if (has_parens && c_ == open_paren_) {
       ++depth_;
-    } else if (has_parens_ && c_ == close_paren_) {
+    } else if (has_parens && c_ == close_paren_) {
       // Failure on unmatched parentheses.
       if (depth_ == 0) {
         FSTERROR() << "CompositeWeightReader: Unmatched close paren: "
-                   << "Is the fst_weight_parentheses flag set correcty?";
+                   << "Is the fst_weight_parentheses flag set correctly?";
         istrm_.clear(std::ios::badbit);
         return false;
       }
@@ -301,17 +339,18 @@ inline bool CompositeWeightReader::ReadElement(T *comp, bool last) {
   }
   if (s.empty()) {
     FSTERROR() << "CompositeWeightReader: Empty element: "
-               << "Is the fst_weight_parentheses flag set correcty?";
+               << "Is the fst_weight_parentheses flag set correctly?";
     istrm_.clear(std::ios::badbit);
     return false;
   }
   std::istringstream istrm(s);
   istrm >> *comp;
   // Skips separator/close parenthesis.
-  if (c_ != EOF && !std::isspace(c_)) c_ = istrm_.get();
+  const bool is_eof = c_ == std::istream::traits_type::eof();
+  if (!is_eof && !std::isspace(c_)) c_ = istrm_.get();
   // Clears fail bit if just EOF.
-  if (c_ == EOF && !istrm_.bad()) istrm_.clear(std::ios::eofbit);
-  return c_ != EOF && !std::isspace(c_);
+  if (is_eof && !istrm_.bad()) istrm_.clear(std::ios::eofbit);
+  return !is_eof && !std::isspace(c_);
 }
 
 }  // namespace fst
index f5339bc..835b127 100644 (file)
@@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.cc flags.cc fst.cc properties.cc symbol-table.cc util.cc \
                     symbol-table-ops.cc mapped-file.cc weight.cc
-libfst_la_LDFLAGS = -version-info 7:0:0
+libfst_la_LDFLAGS = -version-info 8:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index c561aca..893937c 100644 (file)
@@ -336,7 +336,7 @@ lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.cc flags.cc fst.cc properties.cc symbol-table.cc util.cc \
                     symbol-table-ops.cc mapped-file.cc weight.cc
 
-libfst_la_LDFLAGS = -version-info 7:0:0
+libfst_la_LDFLAGS = -version-info 8:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index 66fa720..75a06ef 100644 (file)
@@ -73,8 +73,7 @@ SymbolTable *CompactSymbolTable(const SymbolTable &syms) {
 }
 
 SymbolTable *FstReadSymbols(const string &filename, bool input_symbols) {
-  std::ifstream in(filename.c_str(),
-                        std::ios_base::in | std::ios_base::binary);
+  std::ifstream in(filename, std::ios_base::in | std::ios_base::binary);
   if (!in) {
     LOG(ERROR) << "FstReadSymbols: Can't open file " << filename;
     return nullptr;
index 6109283..3185fc7 100644 (file)
@@ -46,12 +46,6 @@ int64 StrToInt64(const string &s, const string &src, size_t nline,
   return n;
 }
 
-void Int64ToStr(int64 n, string *s) {
-  std::ostringstream nstr;
-  nstr << n;
-  s->append(nstr.str().data(), nstr.str().size());
-}
-
 void ConvertToLegalCSymbol(string *s) {
   for (auto it = s->begin(); it != s->end(); ++it) {
     if (!isalnum(*it)) {
index d7b272a..b34dd0a 100644 (file)
@@ -12,68 +12,88 @@ DEFINE_string(fst_weight_parentheses, "",
 
 namespace fst {
 
-CompositeWeightWriter::CompositeWeightWriter(std::ostream &ostrm)
-    : ostrm_(ostrm), i_(0) {
+namespace internal {
+
+CompositeWeightIO::CompositeWeightIO(char separator,
+                                     std::pair<char, char> parentheses)
+    : separator_(separator),
+      open_paren_(parentheses.first),
+      close_paren_(parentheses.second),
+      error_(false) {
+  if ((open_paren_ == 0 || close_paren_ == 0) && open_paren_ != close_paren_) {
+    FSTERROR() << "Invalid configuration of weight parentheses: "
+               << static_cast<int>(open_paren_) << " "
+               << static_cast<int>(close_paren_);
+    error_ = true;
+  }
+}
+
+CompositeWeightIO::CompositeWeightIO()
+    : CompositeWeightIO(FLAGS_fst_weight_separator.empty()
+                            ? 0
+                            : FLAGS_fst_weight_separator.front(),
+                        {FLAGS_fst_weight_parentheses.empty()
+                             ? 0
+                             : FLAGS_fst_weight_parentheses[0],
+                         FLAGS_fst_weight_parentheses.size() < 2
+                             ? 0
+                             : FLAGS_fst_weight_parentheses[1]}) {
   if (FLAGS_fst_weight_separator.size() != 1) {
-    FSTERROR() << "CompositeWeightWriter: "
+    FSTERROR() << "CompositeWeight: "
                << "FLAGS_fst_weight_separator.size() is not equal to 1";
-    ostrm.clear(std::ios::badbit);
-    return;
+    error_ = true;
   }
-  if (!FLAGS_fst_weight_parentheses.empty()) {
-    if (FLAGS_fst_weight_parentheses.size() != 2) {
-      FSTERROR() << "CompositeWeightWriter: "
-                 << "FLAGS_fst_weight_parentheses.size() is not equal to 2";
-      ostrm.clear(std::ios::badbit);
-      return;
-    }
+  if (!FLAGS_fst_weight_parentheses.empty() &&
+      FLAGS_fst_weight_parentheses.size() != 2) {
+    FSTERROR() << "CompositeWeight: "
+               << "FLAGS_fst_weight_parentheses.size() is not equal to 2";
+    error_ = true;
   }
 }
 
+}  // namespace internal
+
+CompositeWeightWriter::CompositeWeightWriter(std::ostream &ostrm)
+    : ostrm_(ostrm) {
+  if (error()) ostrm.clear(std::ios::badbit);
+}
+
+CompositeWeightWriter::CompositeWeightWriter(std::ostream &ostrm,
+                                             char separator,
+                                             std::pair<char, char> parentheses)
+    : internal::CompositeWeightIO(separator, parentheses), ostrm_(ostrm) {
+  if (error()) ostrm_.clear(std::ios::badbit);
+}
+
 void CompositeWeightWriter::WriteBegin() {
-  if (!FLAGS_fst_weight_parentheses.empty()) {
-    ostrm_ << FLAGS_fst_weight_parentheses[0];
+  if (open_paren_ != 0) {
+    ostrm_ << open_paren_;
   }
 }
 
 void CompositeWeightWriter::WriteEnd() {
-  if (!FLAGS_fst_weight_parentheses.empty()) {
-    ostrm_ << FLAGS_fst_weight_parentheses[1];
+  if (close_paren_ != 0) {
+    ostrm_ << close_paren_;
   }
 }
 
 CompositeWeightReader::CompositeWeightReader(std::istream &istrm)
-    : istrm_(istrm),
-      c_(0),
-      has_parens_(false),
-      depth_(0),
-      open_paren_(0),
-      close_paren_(0) {
-  if (FLAGS_fst_weight_separator.size() != 1) {
-    FSTERROR() << "ComposeWeightReader: "
-               << "FLAGS_fst_weight_separator.size() is not equal to 1";
-    istrm_.clear(std::ios::badbit);
-    return;
-  }
-  separator_ = FLAGS_fst_weight_separator[0];
-  if (!FLAGS_fst_weight_parentheses.empty()) {
-    if (FLAGS_fst_weight_parentheses.size() != 2) {
-      FSTERROR() << "ComposeWeightReader: "
-                 << "FLAGS_fst_weight_parentheses.size() is not equal to 2";
-      istrm_.clear(std::ios::badbit);
-      return;
-    }
-    has_parens_ = true;
-    open_paren_ = FLAGS_fst_weight_parentheses[0];
-    close_paren_ = FLAGS_fst_weight_parentheses[1];
-  }
+    : istrm_(istrm) {
+  if (error()) istrm_.clear(std::ios::badbit);
+}
+
+CompositeWeightReader::CompositeWeightReader(std::istream &istrm,
+                                             char separator,
+                                             std::pair<char, char> parentheses)
+    : internal::CompositeWeightIO(separator, parentheses), istrm_(istrm) {
+  if (error()) istrm_.clear(std::ios::badbit);
 }
 
 void CompositeWeightReader::ReadBegin() {
   do {  // Skips whitespace.
     c_ = istrm_.get();
   } while (std::isspace(c_));
-  if (has_parens_) {
+  if (open_paren_ != 0) {
     if (c_ != open_paren_) {
       FSTERROR() << "CompositeWeightReader: Open paren missing: "
                  << "fst_weight_parentheses flag set correcty?";
index 555a04b..85df5c1 100644 (file)
@@ -2,16 +2,16 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstscript.la
-libfstscript_la_SOURCES = arciterator-class.cc arcsort.cc closure.cc \
-compile.cc compose.cc concat.cc connect.cc convert.cc decode.cc determinize.cc \
-difference.cc disambiguate.cc draw.cc encode.cc encodemapper-class.cc \
-epsnormalize.cc equal.cc equivalent.cc fst-class.cc getters.cc info.cc \
-intersect.cc invert.cc isomorphic.cc map.cc minimize.cc print.cc project.cc \
-prune.cc push.cc randequivalent.cc randgen.cc relabel.cc replace.cc \
-reverse.cc reweight.cc rmepsilon.cc 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_SOURCES = arciterator-class.cc arcsort.cc closure.cc        \
+compile.cc compose.cc concat.cc connect.cc convert.cc decode.cc             \
+determinize.cc difference.cc disambiguate.cc draw.cc encode.cc              \
+encodemapper-class.cc epsnormalize.cc equal.cc equivalent.cc fst-class.cc   \
+getters.cc info-impl.cc info.cc intersect.cc invert.cc isomorphic.cc map.cc \
+minimize.cc print.cc project.cc prune.cc push.cc randequivalent.cc          \
+randgen.cc relabel.cc replace.cc reverse.cc reweight.cc rmepsilon.cc        \
+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 7:0:0
+libfstscript_la_LDFLAGS = -version-info 8:0:0
 endif
index 9e620e0..34f4ca9 100644 (file)
@@ -130,8 +130,8 @@ am__libfstscript_la_SOURCES_DIST = arciterator-class.cc arcsort.cc \
        convert.cc decode.cc determinize.cc difference.cc \
        disambiguate.cc draw.cc encode.cc encodemapper-class.cc \
        epsnormalize.cc equal.cc equivalent.cc fst-class.cc getters.cc \
-       info.cc intersect.cc invert.cc isomorphic.cc map.cc \
-       minimize.cc print.cc project.cc prune.cc push.cc \
+       info-impl.cc info.cc intersect.cc invert.cc isomorphic.cc \
+       map.cc minimize.cc print.cc project.cc prune.cc push.cc \
        randequivalent.cc randgen.cc relabel.cc replace.cc reverse.cc \
        reweight.cc rmepsilon.cc shortest-distance.cc shortest-path.cc \
        stateiterator-class.cc synchronize.cc text-io.cc topsort.cc \
@@ -142,11 +142,11 @@ am__libfstscript_la_SOURCES_DIST = arciterator-class.cc arcsort.cc \
 @HAVE_SCRIPT_TRUE@     determinize.lo difference.lo disambiguate.lo \
 @HAVE_SCRIPT_TRUE@     draw.lo encode.lo encodemapper-class.lo \
 @HAVE_SCRIPT_TRUE@     epsnormalize.lo equal.lo equivalent.lo \
-@HAVE_SCRIPT_TRUE@     fst-class.lo getters.lo info.lo intersect.lo \
-@HAVE_SCRIPT_TRUE@     invert.lo isomorphic.lo map.lo minimize.lo \
-@HAVE_SCRIPT_TRUE@     print.lo project.lo prune.lo push.lo \
-@HAVE_SCRIPT_TRUE@     randequivalent.lo randgen.lo relabel.lo \
-@HAVE_SCRIPT_TRUE@     replace.lo reverse.lo reweight.lo \
+@HAVE_SCRIPT_TRUE@     fst-class.lo getters.lo info-impl.lo info.lo \
+@HAVE_SCRIPT_TRUE@     intersect.lo invert.lo isomorphic.lo map.lo \
+@HAVE_SCRIPT_TRUE@     minimize.lo print.lo project.lo prune.lo \
+@HAVE_SCRIPT_TRUE@     push.lo randequivalent.lo randgen.lo \
+@HAVE_SCRIPT_TRUE@     relabel.lo replace.lo reverse.lo reweight.lo \
 @HAVE_SCRIPT_TRUE@     rmepsilon.lo shortest-distance.lo \
 @HAVE_SCRIPT_TRUE@     shortest-path.lo stateiterator-class.lo \
 @HAVE_SCRIPT_TRUE@     synchronize.lo text-io.lo topsort.lo \
@@ -359,18 +359,18 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstscript.la
-@HAVE_SCRIPT_TRUE@libfstscript_la_SOURCES = arciterator-class.cc arcsort.cc closure.cc \
-@HAVE_SCRIPT_TRUE@compile.cc compose.cc concat.cc connect.cc convert.cc decode.cc determinize.cc \
-@HAVE_SCRIPT_TRUE@difference.cc disambiguate.cc draw.cc encode.cc encodemapper-class.cc \
-@HAVE_SCRIPT_TRUE@epsnormalize.cc equal.cc equivalent.cc fst-class.cc getters.cc info.cc \
-@HAVE_SCRIPT_TRUE@intersect.cc invert.cc isomorphic.cc map.cc minimize.cc print.cc project.cc \
-@HAVE_SCRIPT_TRUE@prune.cc push.cc randequivalent.cc randgen.cc relabel.cc replace.cc \
-@HAVE_SCRIPT_TRUE@reverse.cc reweight.cc rmepsilon.cc shortest-distance.cc shortest-path.cc \
-@HAVE_SCRIPT_TRUE@stateiterator-class.cc synchronize.cc text-io.cc topsort.cc union.cc \
-@HAVE_SCRIPT_TRUE@weight-class.cc verify.cc
+@HAVE_SCRIPT_TRUE@libfstscript_la_SOURCES = arciterator-class.cc arcsort.cc closure.cc        \
+@HAVE_SCRIPT_TRUE@compile.cc compose.cc concat.cc connect.cc convert.cc decode.cc             \
+@HAVE_SCRIPT_TRUE@determinize.cc difference.cc disambiguate.cc draw.cc encode.cc              \
+@HAVE_SCRIPT_TRUE@encodemapper-class.cc epsnormalize.cc equal.cc equivalent.cc fst-class.cc   \
+@HAVE_SCRIPT_TRUE@getters.cc info-impl.cc info.cc intersect.cc invert.cc isomorphic.cc map.cc \
+@HAVE_SCRIPT_TRUE@minimize.cc print.cc project.cc prune.cc push.cc randequivalent.cc          \
+@HAVE_SCRIPT_TRUE@randgen.cc relabel.cc replace.cc reverse.cc reweight.cc rmepsilon.cc        \
+@HAVE_SCRIPT_TRUE@shortest-distance.cc shortest-path.cc stateiterator-class.cc synchronize.cc \
+@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 7:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 8:0:0
 all: all-am
 
 .SUFFIXES:
@@ -470,6 +470,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/equivalent.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst-class.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getters.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info-impl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intersect.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invert.Plo@am__quote@
index 142f166..ced06de 100644 (file)
@@ -48,8 +48,7 @@ FstT *ReadFst(std::istream &istrm, const string &fname) {
 
 FstClass *FstClass::Read(const string &fname) {
   if (!fname.empty()) {
-    std::ifstream istrm(fname.c_str(),
-                             std::ios_base::in | std::ios_base::binary);
+    std::ifstream istrm(fname, std::ios_base::in | std::ios_base::binary);
     return ReadFst<FstClass>(istrm, fname);
   } else {
     return ReadFst<FstClass>(std::cin, "standard input");
@@ -86,8 +85,7 @@ bool FstClass::WeightTypesMatch(const WeightClass &weight,
 MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
   if (convert == false) {
     if (!fname.empty()) {
-      std::ifstream in(fname.c_str(),
-                            std::ios_base::in | std::ios_base::binary);
+      std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
       return ReadFst<MutableFstClass>(in, fname);
     } else {
       return ReadFst<MutableFstClass>(std::cin, "standard input");
@@ -109,8 +107,7 @@ MutableFstClass *MutableFstClass::Read(const string &fname, bool convert) {
 
 VectorFstClass *VectorFstClass::Read(const string &fname) {
   if (!fname.empty()) {
-    std::ifstream in(fname.c_str(),
-                          std::ios_base::in | std::ios_base::binary);
+    std::ifstream in(fname, std::ios_base::in | std::ios_base::binary);
     return ReadFst<VectorFstClass>(in, fname);
   } else {
     return ReadFst<VectorFstClass>(std::cin, "standard input");
diff --git a/src/script/info-impl.cc b/src/script/info-impl.cc
new file mode 100644 (file)
index 0000000..1d7c9bb
--- /dev/null
@@ -0,0 +1,101 @@
+#include <fst/script/info-impl.h>
+
+namespace fst {
+
+void PrintFstInfoImpl(const FstInfo &fstinfo, bool pipe) {
+  std::ostream &ostrm = pipe ? std::cerr : std::cout;
+  const auto old = ostrm.setf(std::ios::left);
+  ostrm.width(50);
+  ostrm << "fst type" << fstinfo.FstType() << std::endl;
+  ostrm.width(50);
+  ostrm << "arc type" << fstinfo.ArcType() << std::endl;
+  ostrm.width(50);
+  ostrm << "input symbol table" << fstinfo.InputSymbols() << std::endl;
+  ostrm.width(50);
+  ostrm << "output symbol table" << fstinfo.OutputSymbols() << std::endl;
+  if (!fstinfo.LongInfo()) {
+    ostrm.setf(old);
+    return;
+  }
+  ostrm.width(50);
+  ostrm << "# of states" << fstinfo.NumStates() << std::endl;
+  ostrm.width(50);
+  ostrm << "# of arcs" << fstinfo.NumArcs() << std::endl;
+  ostrm.width(50);
+  ostrm << "initial state" << fstinfo.Start() << std::endl;
+  ostrm.width(50);
+  ostrm << "# of final states" << fstinfo.NumFinal() << std::endl;
+  ostrm.width(50);
+  ostrm << "# of input/output epsilons" << fstinfo.NumEpsilons() << std::endl;
+  ostrm.width(50);
+  ostrm << "# of input epsilons" << fstinfo.NumInputEpsilons() << std::endl;
+  ostrm.width(50);
+  ostrm << "# of output epsilons" << fstinfo.NumOutputEpsilons() << std::endl;
+  ostrm.width(50);
+  ostrm << "input label multiplicity" << fstinfo.InputLabelMultiplicity()
+        << std::endl;
+  ostrm.width(50);
+  ostrm << "output label multiplicity" << fstinfo.OutputLabelMultiplicity()
+        << std::endl;
+  ostrm.width(50);
+  string arc_type = "";
+  if (fstinfo.ArcFilterType() == "epsilon")
+    arc_type = "epsilon ";
+  else if (fstinfo.ArcFilterType() == "iepsilon")
+    arc_type = "input-epsilon ";
+  else if (fstinfo.ArcFilterType() == "oepsilon")
+    arc_type = "output-epsilon ";
+  const auto accessible_label = "# of " + arc_type + "accessible states";
+  ostrm.width(50);
+  ostrm << accessible_label << fstinfo.NumAccessible() << std::endl;
+  const auto coaccessible_label = "# of " + arc_type + "coaccessible states";
+  ostrm.width(50);
+  ostrm << coaccessible_label << fstinfo.NumCoAccessible() << std::endl;
+  const auto connected_label = "# of " + arc_type + "connected states";
+  ostrm.width(50);
+  ostrm << connected_label << fstinfo.NumConnected() << std::endl;
+  const auto numcc_label = "# of " + arc_type + "connected components";
+  ostrm.width(50);
+  ostrm << numcc_label << fstinfo.NumCc() << std::endl;
+  const auto numscc_label = "# of " + arc_type + "strongly conn components";
+  ostrm.width(50);
+  ostrm << numscc_label << fstinfo.NumScc() << std::endl;
+  ostrm.width(50);
+  ostrm << "input matcher"
+        << (fstinfo.InputMatchType() == MATCH_INPUT
+                ? 'y'
+                : fstinfo.InputMatchType() == MATCH_NONE ? 'n' : '?')
+        << std::endl;
+  ostrm.width(50);
+  ostrm << "output matcher"
+        << (fstinfo.OutputMatchType() == MATCH_OUTPUT
+                ? 'y'
+                : fstinfo.OutputMatchType() == MATCH_NONE ? 'n' : '?')
+        << std::endl;
+  ostrm.width(50);
+  ostrm << "input lookahead" << (fstinfo.InputLookAhead() ? 'y' : 'n')
+        << std::endl;
+  ostrm.width(50);
+  ostrm << "output lookahead" << (fstinfo.OutputLookAhead() ? 'y' : 'n')
+        << std::endl;
+  uint64 prop = 1;
+  for (auto i = 0; i < 64; ++i, prop <<= 1) {
+    if (prop & kBinaryProperties) {
+      char value = 'n';
+      if (fstinfo.Properties() & prop) value = 'y';
+      ostrm.width(50);
+      ostrm << PropertyNames[i] << value << std::endl;
+    } else if (prop & kPosTrinaryProperties) {
+      char value = '?';
+      if (fstinfo.Properties() & prop)
+        value = 'y';
+      else if (fstinfo.Properties() & prop << 1)
+        value = 'n';
+      ostrm.width(50);
+      ostrm << PropertyNames[i] << value << std::endl;
+    }
+  }
+  ostrm.setf(old);
+}
+
+}  // namespace fst
index f800e8d..4af5117 100644 (file)
@@ -17,9 +17,20 @@ void PrintFstInfo(const FstClass &fst, bool test_properties,
   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) {
+  GetInfoArgs args(fst, test_properties, arc_filter, info_type, verify, result);
+  Apply<Operation<GetInfoArgs>>("GetFstInfo", fst.ArcType(), &args);
+}
+
 REGISTER_FST_OPERATION(PrintFstInfo, StdArc, InfoArgs);
 REGISTER_FST_OPERATION(PrintFstInfo, LogArc, InfoArgs);
 REGISTER_FST_OPERATION(PrintFstInfo, Log64Arc, InfoArgs);
 
+REGISTER_FST_OPERATION(GetFstInfo, StdArc, GetInfoArgs);
+REGISTER_FST_OPERATION(GetFstInfo, LogArc, GetInfoArgs);
+REGISTER_FST_OPERATION(GetFstInfo, Log64Arc, GetInfoArgs);
+
 }  // namespace script
 }  // namespace fst
index 17c69d5..73b8907 100644 (file)
@@ -20,8 +20,8 @@ namespace script {
 // Reads vector of weights; returns true on success.
 bool ReadPotentials(const string &weight_type, const string &filename,
                     std::vector<WeightClass> *potentials) {
-  std::ifstream strm(filename.c_str());
-  if (!strm.good()) {
+  std::ifstream istrm(filename);
+  if (!istrm.good()) {
     LOG(ERROR) << "ReadPotentials: Can't open file: " << filename;
     return false;
   }
@@ -29,7 +29,7 @@ bool ReadPotentials(const string &weight_type, const string &filename,
   char line[kLineLen];
   size_t nline = 0;
   potentials->clear();
-  while (!strm.getline(line, kLineLen).fail()) {
+  while (!istrm.getline(line, kLineLen).fail()) {
     ++nline;
     std::vector<char *> col;
     SplitToVector(line, "\n\t ", &col, true);
@@ -39,8 +39,8 @@ bool ReadPotentials(const string &weight_type, const string &filename,
                  << "file = " << filename << ", line = " << nline;
       return false;
     }
-    ssize_t s = StrToInt64(col[0], filename, nline, false);
-    WeightClass weight(weight_type, col[1]);
+    const ssize_t s = StrToInt64(col[0], filename, nline, false);
+    const WeightClass weight(weight_type, col[1]);
     while (potentials->size() <= s) {
       potentials->push_back(WeightClass::Zero(weight_type));
     }
@@ -52,22 +52,25 @@ bool ReadPotentials(const string &weight_type, const string &filename,
 // Writes vector of weights; returns true on success.
 bool WritePotentials(const string &filename,
                      const std::vector<WeightClass> &potentials) {
-  std::ofstream fstrm;
+  std::ofstream ostrm;
   if (!filename.empty()) {
-    fstrm.open(filename.c_str());
-    if (!fstrm) {
+    ostrm.open(filename);
+    if (!ostrm.good()) {
       LOG(ERROR) << "WritePotentials: Can't open file: " << filename;
       return false;
     }
   }
-  std::ostream &ostrm = fstrm.is_open() ? fstrm : std::cout;
-  ostrm.precision(9);
-  for (auto s = 0; s < potentials.size(); ++s)
-    ostrm << s << "\t" << potentials[s] << "\n";
-  if (ostrm.fail())
+  std::ostream &strm = ostrm.is_open() ? ostrm : std::cout;
+  strm.precision(9);
+  for (size_t s = 0; s < potentials.size(); ++s) {
+    strm << s << "\t" << potentials[s] << "\n";
+  }
+  if (strm.fail()) {
     LOG(ERROR) << "WritePotentials: Write failed: "
                << (filename.empty() ? "standard output" : filename);
-  return !ostrm;
+    return false;
+  }
+  return true;
 }
 
 }  // namespace script
index 0ebd2f4..2a3c5d7 100644 (file)
@@ -373,6 +373,7 @@ class WeightedTester {
       std::vector<Label> labelset(kNumLabels);
       for (size_t i = 0; i < kNumLabels; ++i) labelset[i] = i;
       for (size_t i = 0; i < kNumLabels; ++i) {
+        using std::swap;
         swap(labelset[i], labelset[rand() % kNumLabels]);
       }
 
index caf3c10..7176929 100644 (file)
@@ -18,7 +18,7 @@ namespace {
 
 // A user-defined arc type.
 struct CustomArc {
-  typedef short Label;
+  typedef int16 Label;
   typedef ProductWeight<TropicalWeight, LogWeight> Weight;
   typedef int64 StateId;
 
@@ -27,8 +27,8 @@ struct CustomArc {
   CustomArc() {}
 
   static const string &Type() {  // Arc type name
-    static const string type = "my";
-    return type;
+    static const string *const type = new string("my");
+    return *type;
   }
 
   Label ilabel;       // Transition input label
@@ -63,8 +63,8 @@ class CustomCompactor {
   bool Compatible(const Fst<A> &fst) const { return true; }
 
   static const string &Type() {
-    static const string type = "my";
-    return type;
+    static const string *const type = new string("my");
+    return *type;
   }
 
   bool Write(std::ostream &strm) const { return true; }
index 9596aca..7d536d9 100644 (file)
@@ -217,13 +217,13 @@ class FstTester {
     {
       // check mmaping by first writing the file with the aligned attribute set
       {
-        std::ofstream ostr(aligned.c_str());
+        std::ofstream ostr(aligned);
         FstWriteOptions opts;
         opts.source = aligned;
         opts.align = true;
         CHECK(fst.Write(ostr, opts));
       }
-      std::ifstream istr(aligned.c_str());
+      std::ifstream istr(aligned);
       FstReadOptions opts;
       opts.mode = FstReadOptions::ReadMode("map");
       opts.source = aligned;
@@ -236,13 +236,13 @@ class FstTester {
     // check mmaping of unaligned files to make sure it does not fail.
     {
       {
-        std::ofstream ostr(aligned.c_str());
+        std::ofstream ostr(aligned);
         FstWriteOptions opts;
         opts.source = aligned;
         opts.align = false;
         CHECK(fst.Write(ostr, opts));
       }
-      std::ifstream istr(aligned.c_str());
+      std::ifstream istr(aligned);
       FstReadOptions opts;
       opts.mode = FstReadOptions::ReadMode("map");
       opts.source = aligned;